垂れ流す思考

思考を垂れ流しアウトプットを行うブログ

ふつうのHaskellプログラミング 第3章 - 1

ふつうのHaskellプログラミング

ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門

ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門

噂のすごいH本を読んで楽しくHaskellを学んでいこうというコンセプト

会社のHaskellerさんに
「関数型素人がすごいH本で入門すると中盤で詰むよ」
「初めてならふつうのH本からがおすすめ」
ということなので『ふつうのHaskellプログラミング』からやっていこうかと。

第3章 Haskellの基礎(2)型と高階関数 - 1

型と値

型推論の話が登場する。型推論は最近の言語には結構盛り込まれているが言語によってはかなり解釈が異なっているらしい。
参考: https://qiita.com/kmizu/items/2ace816340e8553bd278
RubyJavascriptしかやってない動的型付け言語マンの自分はこの辺の話題はよくわからない。型...?まぁそうですね...みたいな感じ。
Rubyみたいに型宣言しなくても書けるけどRubyより安全に書けて、賢く型を補完してくれるみたいな解釈でいいのかな。


型変数 [a] -> Int
[]はリストの意味なので「aのリスト」と言う意味。aは型変数(type variable)といってどんな値でもいいよって意味。
型変数が含まれている型を多相型(polymorphic type)と言う。
PolymorphicってRailsのActive recordにあったな。
型変数は一文字ならなんでもいいらしいけど慣習的にa, b, c, ...と使っていくらしい。


関数の型宣言
これはいい書き方だなぁと。Haskellのコードってなんか怖い印象あったけど読み方わかると納得。
関数名 :: 第一引数の型 -> 第二引数の型 -> ... -> 返り値の型
func' :: Int -> Int -> Int
関数の型宣言ってめんどくさかったけどこんな感じで書けるならいいなぁ、Javascriptのコメントで書こうかな。


高階関数(Higher order function)

Rubyだとブロック要素が高階関数に当たる。そこまで実感はない。
引数に評価前の関数をとる関数のことを指す。
評価後の返り値を使うのは高階関数とは言わない。
この辺は使って行って慣れで覚えるしかないかな〜。


if式
Huskellはif文ではなく式なので常に値を返す。これはRubyと同じ。
条件式の値はbool値じゃないとエラーになる。これはRubyと違う(Rubyはfalseとnil以外はtrue)


==演算子
(==) :: a -> a -> Bool
こんな感じで型宣言を考えながら使えばエラーが減りそう。


同一性と同値性

これはちょっと目から鱗なコラムだった。 オブジェクト指向言語だと値が同じとオブジェクトが同じかの二種類ある。
参考: Ruby の文字列比較 [eql?, equal?, ==, ===] の使い分けを汗臭く説明 #ruby
結構めんどくさいけどHaskellには同値性以外はないので一本化できると言うこと。
細かいようで重要なのかな。


余談

# expand0.hs
main = do cs <- getContents
          putStr $ expand cs

expand :: String -> String
expand cs = map translate cs

translate :: Char -> Char
translate c = if c == '\t' then '@' else c

このexpand.hsバージョン0のコードを使うとHlintで怒られる。

Warning: Eta reduce. Found: expand cs = map translate cs Why not: expand = map translate

う〜ん。要はexpand cs = map translate csexpand = map translateになんでしないの?って感じ。

実際下記で警告は消えるし、ちゃんと動く。

# expand0.hs
main = do cs <- getContents
          putStr $ expand cs

expand :: String -> String
expand = map translate

translate :: Char -> Char
translate c = if c == '\t' then '@' else c

なんとなく意味はわかるけど説明できないから警告文: Eta reduceは次回の課題だな。

今回はここまで。

ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門

ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門