Haskell の文字列は, 歴史的な事情で, 若干複雑になっています。
1文字を表すのは Char
型です。値の意味は Unicode code point です。なので、厳密には「文字」ではない。
リテラルは「'
」で文字を囲みます。
Prelude> :type 'あ' 'あ' :: Char
文字リテラルでは, \x
に続けて16進数で10ffffまでのcode point を指定できます。これを超える値の場合は out of range エラー。
Char
型は次の型クラスのインスタンスです。
Bounded
Enum
Eq
Data
Ord
Read
Show
Ix
Storable
IsChar
PrintfArg
TODO: このほか data family URec
のインスタンス?
組込みの文字列型は String
です。String
は [Char]
, つまりCharのリスト型の別名になっています。
String
は素朴な1文字単位のリストなので, 想像どおり, パフォーマンスに難があります。過去との互換性のために残っています。
新しいプログラムでは, バイト列がほしいときは ByteString
, 文字列がほしいときは Text
データ型を使ってください。
type String = [Char] -- Defined in `GHC.Base'
リテラルは「"
」で囲みます。String型は単なるリストなので、その値の操作については, リストに適用できる関数がそのまま使えます。
次のプログラムは, ファイルの先頭を表示します。
それぞれの関数:
readFile :: FilePath -> IO String
lines :: String -> [String]
ただし, 元の文字列の末尾の改行文字は単に除去されるため, 元の文字列に厳密に復元できるようにはなっていません。
Prelude> lines "fuga\r\n" ["fuga\r"]
take :: Int -> [a] -> [a]
unlines :: [String] -> String
do
ブロックについては, またページを替えて説明しますが, とりあえずここでは,
<-
キーワードで, 右辺のアクション (IO a型の値) を左辺のa型の定数に割り当てることができます。
ByteString
データ型bytestring パッケージの Data.ByteString
モジュール, ByteString
データ型は, 単なるバイトの配列です。型名に〜Stringが含まれていますが, 文字列は関係ありません。
ByteString は, 次の型クラスのインスタンスです。
Eq
Data
Ord
Read
Show
IsString
Monoid
NFData
とはいえ, 単に右から左へデータを移すようなときは, ByteString が使えます。
OverloadedStrings
で、文字列リテラルが String
型以外になりえます。IsString
型クラスのインスタンス (で型が合うもの) になる。
実行例
何か入力> ああ愛 str = ああ愛 9 bytes
単にそのまま表示するだけなら, ただのバイト列なので, 化けません。この例だと, 文字数は UTF-8によるバイト数の9になっています。
本物の文字列は, Text
型です。
入出力は ByteString を使い, 文字列に変換して使います。
"str2.txt"ファイル (UTF-8で保存。)
あああAbc23はひふ
実行結果:
$ runhaskell str2.hs 12
改行文字込みで, 正しく12文字とカウントできている。
Text型については、別ページに続きます; テキスト型の周辺