ラムダ式
ラムダ式とは、1回だけ必要な関数を作る時に使う無名関数です。
通常、高階関数に渡す関数を作るためだけに使われるらしい
バックスラッシュを書いてからこのようにする。
(\{引数1} {引数2} -> {関数本体})
普通、ラムダ式は括弧で囲むとのこと。
numLongChains :: Int numLongChains = length (filter (\xs -> length xs > 15) (map chain [1..100]))
実行結果
*Main> numLongChains 66
カリー化と部分適用の動作がよくわかってないと、必要ないところでラムダ式使いがちになるらしい。
*Main> map (+3) [1,2,3,4] [4,5,6,7] *Main> map (\x -> x + 3) [1,2,3,4] [4,5,6,7]
これは部分適用のほうが可読性が高い例
ラムダ式は任意の数の引数を取ることができる
*Main> zipWith (\a b -> (a * 30 + 3) / b) [5,4,3,2,1] [1,2,3,4,5] [153.0,61.5,31.0,15.75,6.6]
ラムダ式でもパターンマッチができる
*Main> map (\(a, b) -> a + b) [(1,2),(3,4),(5,6)] [3,7,11]
ラムダ式でパターンマッチが失敗したら、ランタイムエラーが発生するので注意すること。
addThree :: Int -> Int -> Int -> Int addThree x y z = x + y + z addThree' :: Int -> Int -> Int -> Int addThree' = \x -> \y -> \z -> x + y + z
関数はデフォルトでカリー化されているので上の2つの関数は等価らしい。
この場合、前者のほうが可読性が高い。
ラムダ式を括弧なしで書いた場合、->
の右側のすべてがそのラムダ式に属する。
カリー化の方がよい場合もある。
flip' :: (a -> b -> c) -> b -> a -> c flip' f = \x y -> f x y
こちらのほうが「引数を入れ替えた関数を返す」ということがコードから伝わりやすい。
flip で一番多い使い方は、引数として関数のみ、もしくは関数と引数を1つだけ渡し、生成された関数を map や zipWith に渡すという方法がある。
*Main> zipWith (flip (++)) ["love you", "love me"] ["i ", "you "] ["i love you","you love me"] *Main> map (flip subtract 20) [1,2,3,4] [19,18,17,16]
所感
vim2hs
の\
をλ
に勝手に変えてくれる機能でカーソル位置がずれまくってたので以下の設定をOFFにした。
let g:haskell_conceal = 0
以前わからんと言っていた flip の具体的な使い方が出てきた。flip subtract 20
はわかりやすい。が、自分で書くとなると書けないと思う。
周りの Haskeller はわからんと言ってたら教えてくれるのでとても感謝しています。ありがとう。

- 作者: MiranLipovaca
- 出版社/メーカー: オーム社
- 発売日: 2017/07/14
- メディア: Kindle版
- 購入: 4人 クリック: 9回
- この商品を含むブログを見る