トップ «前の日記(2007-05-10) 最新 次の日記(2007-05-20)» 編集

Route 477



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 + bx `f` y
前置記法(+) a bf 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です。

お疲れ様でした。

[misc] 最近調子が悪いもの

周辺機器がいろいろヤバい。

HHKB

ゲームをプレイしてるとときどき「→」キーが勝手に入力される。ゲームにならん。

これはハック以外はするなというHHKBの意思か…?

外付けHDD

こいつをUSBで繋いでるとWindowsがレジュームに失敗する。というかマシン起動時のメモリチェックで固まるので Windowsは関係ない気もするが。

仕方ないので毎回起動時だけUSBケーブルを外している。ダサい。

プリンタ

100%の確率で紙が詰まるので終了。これでは単なるでかいスキャナだ。