関数
8.4 ポイントフリースタイル
むむむ…、なかなか難しい概念ですね。
頭の中を整理すると、要は
関数を式(値)ではなく、式(値)から独立した関数で定義すること
をポイント(値)フリー(独立)スタイルというのかな。
たしかにこれまで関数を定義(関数に変数を束縛)する時、式で定義していました。
たとえば
myMax :: (Int, Int) -> Int myMax (x, x) = 0 myMax (x, y) = if x > y then x else y
では、「0」や「if x > y then x else y」はいずれも式です。
takeLast n ss = reverse $ take n $ reverse ss
もそうですね。「reverse $ take n $ reverse ss」は式です。
だけど、これを次のように書きます。
takeLast n = reverse . take n . reverse
引数(n)は一つ使ってますけど、右辺は関数です。
ちょっと疑問が…。これって次のようにも書けるのかな?
- tail.hs
main = do cs <- getContents putStr $ lastNLines 10 cs lastNLines n cs = unlines $ takeLast n $ lines cs -- takeLast n ss = reverse $ take n $ reverse ss -- takeLast n = reverse . take n . reverse takeLast n = reverse $ take n $ reverse
それっ!
% ghc -W -o tail tail.hs tail.hs:8:32: Couldn't match expected type `[a]' against inferred type `[a1] -> [a1]' In the second argument of `($)', namely `reverse' In the second argument of `($)', namely `take n $ reverse' In the expression: reverse $ take n $ reverse
あれれ、だめですねぇ。
reverse関数の型は[a1]->[a1]なのに、[a]で使われているとな。
なるほど、「$」は単に括弧と同じで式をまとめているだけだからね。
「$」に対する理解が深まりました。