Zipリスト
ZipList
という型があり、これは Applicative のインスタンスである。
instance Applicative ZipList where pure x = ZipList (repeat x) ZipList fs <*> ZipList xs = ZipList (zipWith (\f x -> f x) fs xs)
<*>
は1つ目の関数を1つ目の値に、2つめの関数を2つ目の値に、... と適用する。
zipWith の仕様上短い方のリストに合わせた結果となる。
pure
は、引数をとってそれを無限に繰り返すリストを返す。
この定義なら pure f <*> xs
と fmap f xs
が等しい。という法則を満たす。
仮に pure x = ZipList [x]
だった場合、
pure (*2) <*> ZipList [1,5,10]
の結果は ZipList [2]
になってしまう。
2つの有限リストを zip した結果の長さは短い方の長さになるため。 一方、無限リストと有限リストを zip したときの結果のリストの長さは、 有限リストの長さとなる。
ZipList a 型は Show インスタンスをサポートしていないので、
getZipList
を使って生リストを取り出す必要がある。
*Main Control.Applicative> getZipList $ (+) <$> ZipList [1,2,3] <*> ZipList [100,100,100] [101,102,103] *Main Control.Applicative> getZipList $ (+) <$> ZipList [1,2,3] <*> ZipList [100,100..] [101,102,103] *Main Control.Applicative> getZipList $ max <$> ZipList [1,2,3,4,5,3] <*> ZipList [5,3,1,2] [5,3,3,4] *Main Control.Applicative> getZipList $ (,,) <$> ZipList "dog" <*> ZipList "cat" <*> ZipList "rat" [('d','c','r'),('o','a','a'),('g','t','t')]
(,,)
は \x y z -> (x,y,z)
と同じ。
zipWith
以外にも zipWith3
、zipWith7
までの関数がある。
所感
pure
の定義の発想が自分では到底思いつかないようなものだった。自分で書いていけるか不安になった。

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