とりあえず普通のHaskellプログラマが書くであろうフィボナッチ数列の計算:
fib = 1:1:[a + b | (a, b) <- zip fib (tail fib)]
Parallel List Comprehensions を使ってみた書き方:
fib = 1:1:[a + b | a <- fib | b <- tail fib]
Generalised (SQL-Like) List Comprehensionsを(無駄に)使った書き方:
fib = 1:1:[sum a | a <- fib, then group using (\b -> zipWith (\c d->[c,d]) b (tail b))]
こいつは -XTransformListComp で機能を有効する必要あり? とりあえず束縛時と使用時で変数 a の型が変わるのがまぎらわしい.ついでに using の後の関数の型が forall a. [a] -> [[a]] でないといけないのを時々忘れて怒られる.ついでに by をつけたときには forall a. (a -> t) -> [a] -> [[a]] でないと怒られる.第一引数の (a -> t) という型の部分には by の後に指定する式から作られる関数が渡されるので,そこでリストの要素を見て適当な型 t の要素に射影して,その結果を使ってリストの要素をリアレンジしても良いよと.でも,その関数以外ではリストの要素に触れてはいけないよと(forall がついてるから).むずい.
さらに -XViewPatterns を有効にして無駄に分かりにくい書き方をしてみる.機能の無駄遣い.
fib = 1:1:[sum a | a <- fib, then group using (\c@(tail->b)-> zipWith (\((:[])->c) d -> d:c) c b)]
とりあえず,変なプログラムを書いたおかげで Generalised (SQL-Like) List Comprehensions の使い方が分かった(元論文はだいぶ前に読んであったのだけど).
- Newer: ことはじめ