「ふつうのHaskellプログラミング」読みます(5)
6章。基本的な値と、それらまわりの関数とか。
6.2 真偽値
Prelude> not True False Prelude> not True && False False Prelude> False || True True
まあふつう。
6.3 数値
Haskellの整数型はInt、Integer。Intが上限下限ありの整数、Integerが制限無しの整数型。rubyでいうとIntがFixnumでIntegerがBignumみたいな。あと数値リテラルは文脈に合わせて適当な数値型になるらしいです。
Prelude> 9999999999999999999999999999999999999 9999999999999999999999999999999999999 Prelude> 9999999999999999999999999999999999999 :: Int -1
8進数と16進数リテラルあり。
Prelude> 0o11 9 Prelude> 0x11 17
浮動小数点型にはFloatとDoubleあり。
Prelude> 2 :: Double 2.0 Prelude> 11e+4 110000.0 Prelude> 99999999999999999999999999999999999999999999999999 :: Float Infinity Prelude> 99999999999999999999999999999999999999999999999999 :: Double 1.0e50
色々な演算あります。詳しくはdoc/libraries/base/Prelude.htmlとか読めばいいと思う。
Prelude> div 33 7 4 Prelude> mod 33 7 5 Prelude> -88 -88 Prelude> -(88 -80) -8 Prelude> abs $ -8 8 Prelude> floor 3.33 3 Prelude> ceiling 3.33 4
6.4 文字と文字列
文字列は文字のリスト。doc/libraries/haskell98/Char.htmlあたり読むと関数がいろいろのってる。
Prelude Char> isUpper 'a' False Prelude Char> isAlpha 'a' True Prelude Char> isUpper 'a' False Prelude Char> isHexDigit 'a' True Prelude Char> isDigit 'a' False Prelude Char> chr 90 'Z' Prelude Char> ord 'a' 97 Prelude Char> map ord "hogehoge" [104,111,103,101,104,111,103,101]
6.5 タプル
これもOCamlとかでよく使うし知っていた。
Prelude> (3, 2) (3,2) Prelude> fst (3, 2) 3 Prelude> snd (3, 2) 2 Prelude> zip [1, 2, 3, 4, 5] [9, 8, 7] [(1,9),(2,8),(3,7)] Prelude> unzip $ zip [1, 2, 3, 4, 5] [9, 8, 7] ([1,2,3],[9,8,7])
これって(1, 2, 3, 4)とかどうすんだ。パターンマッチで取れつうことか。
6.6 リスト
Schemeとかでさんざん使ったぞ。
Prelude> 1 : 2 : 3 : 4 : [] [1,2,3,4] Prelude> let cons = (:) Prelude> (cons 1 (cons 2 (cons 3 (cons 4 [])))) [1,2,3,4]
やったね! まあそれはいいとして。便利な数列表記なるものあったらしいです。
Prelude> [1..8] [1,2,3,4,5,6,7,8] Prelude> [1, 3..8] [1,3,5,7] Prelude> [1,2..8] [1,2,3,4,5,6,7,8] Prelude> [1,2,3..8] <interactive>:1:6: parse error on input `..'
null, ++といった関数あるよと。
Prelude> null [] True Prelude> null [1] False Prelude> [] ++ [1] [1] Prelude> [1,2] ++ [1] [1,2,1]
内包表記もあります。
Prelude> [abs x | x <- [-10..10]] [10,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,10] Prelude> [x+3 | x <- [0..10]] [3,4,5,6,7,8,9,10,11,12,13] Prelude> [(x,y) | x <- [1,2], y <- ['a'..'c']] [(1,'a'),(1,'b'),(1,'c'),(2,'a'),(2,'b'),(2,'c')] Prelude> [x*y | x <- [1..5], y <- [1..3]] [1,2,3,2,4,6,3,6,9,4,8,12,5,10,15]
6.7 実習
catn.hs
main = do cs <- getContents putStr (numbering cs) numbering cs = unlines (map format (zipLineNumber (lines cs))) zipLineNumber xs = zip [1..] xs format (n, line) = rjust 6 (show n) ++ " " ++ line rjust width s = replicate (width - length s) ' ' ++ s
無限リストとか便利ですねえ。うーん、型は型推論に丸投げってのは楽だけど、まずいかも。読むときにはこっちが型推論する必要性が生まれてくる。
% ghc catn.hs -o catn % ./catn </usr/include/stdio.h 1 /* Define ISO C stdio on top of C++ iostreams. ... 915 916 #endif /* !_STDIO_H */
こうなるわけです。