2007-05-19
■ [event][haskell] Haskell勉強会#4
ブログを書くまでが勉強会らしいので書きます。 (あれ、そういえば氏久さんのブログってないのかな)(5/26追記:あった!)
今日は6.1から6.6まで進みました。
4797336021
関数の型宣言
(&&) :: Bool -> Bool -> Bool
という感じで a && b という演算子の型が定義されるんだけどこれHaskell知らん人から見たら意味不明だよね。 毎回型宣言だけは必ず復習したほうが良さそうだ。
演算子が自分で定義できる
Haskellでは演算子を自分で好きに定義できる(a +++ b とか、a .+. b とか)。 というか記号だけでできた関数名にするとちゅうち記法(←なぜか変換できない)で使えるようになるらしい。
というわけで顔文字演算子を定義してみた。
(^-^) :: String -> String -> String (^-^) x y = x ++ " love " ++ y main = print $ "I" ^-^ "Haskell"
yhara@meteor:~/tmp % runhugs lovehaskell.hs "I love Haskell"
もしくは
main = print $ (^-^) "I" "Haskell"
でも可。
基本的に演算子は中置記法(例:a + b)、普通の関数は前置記法(例:f x y)なのだが、 カッコを付けると演算子も前置記法にできるし(例:(+) a b)、バッククオートでくくると普通の関数も中置記法に できる(例:x `f` y)。
表にしてみる。
表記 | 演算子 | 普通の関数 |
中置記法 | a + b | x `f` y |
前置記法 | (+) a b | f x y |
後置記法はHaskellにはない…ですよね。
上の「ちゅうち記法」っていうのはもちろん中置記法のことなんだけど「ちゅうち」ではなく「なかおき」 と書かないとMS-IMEは変換してくれない。じゃあ「なかおききほう」という読み方が正しいのか!?と一瞬思ったのだが、 実は茶道の用語に「なかおき」というものがあるらしいのであくまでも「ちゅうちきほう」が正しい…と思う。
とか言ってる間に辞書登録しろよっていう話だな。
整数型
HaskellにはInt型(32bitなやつ)とInteger型(任意の大きさが扱えるやつ)の2種類の整数がある。 RubyでいうFixnumとBignumか。 RubyだとFixnumとBignumの区別は特に考えない(勝手に変換される)んだけど、Haskellだとそれらは明確に区別されるようだ。
hugsで実験してみよう。
IntとIntを掛け算すると、オーバーフローして負数になる場合がある。
Prelude> (20000000 :: Int) * (2000000000 :: Int) -1090256896
Integer同士だとオーバーフローはしない。
Prelude> (20000000 :: Integer) * (2000000000 :: Integer) 40000000000000000
型を何も書かないと自動的にIntegerとして扱ってくれるみたいだ(どうなってるんだろう?)
Prelude> (20000000 * 2000000000) 40000000000000000
片方がIntで、片方がIntegerだとType errorになる。
Prelude> (20000000 :: Int) * (2000000000 :: Integer) ERROR - Type error in application *** Expression : 20000000 * 2000000000 *** Term : 20000000 *** Type : Int *** Does not match : Integer
こういう場合はtoIntegerという関数でIntな整数をIntegerに変換してやればいいんだけど、 それもちょっと面倒だよねってことでHaskellの時期仕様ではいろいろ検討されているらしい(ikegamiさん情報)。
zipの話
zipっていうのはこういう風に2つのリストを「横に繋げる」関数。
Prelude> zip [1,2,3] [4,5,6] [(1,4),(2,5),(3,6)]
返り値はタプルのリストになる。
ちなみにRubyにもArray#zipというメソッドがある。
>> [1,2,3].zip([4,5,6]) => [[1, 4], [2, 5], [3, 6]]
RubyにはタプルがないのでArrayのArrayになるけど。
id:ha-tanさんが「Haskellを知るまでなんでこんなメソッドがあるのか分からなかった」と言ってて、激しく同意(笑)。
リスト内包表現
数学で集合を表現するときに { x | ∀x ∈ {1,2,3,4,5,6}, x mod 2 = 0} みたいに書くけど、それがそのまま
Prelude> [x | x <- [1,2,3,4,5,6], x `mod` 2 == 0] [2,4,6]
みたいに表記できる。
もちろんmap関数とfilter関数を使えば書けるんだけど、より数学っぽく掛けて良いよね。という。
打ち上げ:インデアンカレー
やばい。
甘いのに辛いよ。
卵がないと無理。
来週は
るびま読書会#2です。
お疲れ様でした。