foldの呼び出し順を括弧で表示
(あるいはHaskellの型が邪魔だった事例)
irb> [1,2,3].inject(0){|a,b|[a,b]} => [[[0, 1], 2], 3]
まずは素直にリストでやってみる。
Prelude> foldl (\a b->[a,b]) 0 [1,2,3] Occurs check: cannot construct the infinite type: a = [a]
当然出来ない。
次にタプルでやってみる。
Prelude> foldl (\a b->(a,b)) 0 [1,2,3] Occurs check: cannot construct the infinite type: a = (a, b)
これもだめ。
型を合わせるためにshowで文字列化してみる。
Prelude> foldl (\a b->show (a,b)) "0" [1,2,3] "(\"(\\\"(\\\\\\\"0\\\\\\\",1)\\\",2)\",3)"
バックスラッシュがえらいことに。
仕方がないので地道に++でつなぐことにする。
Prelude> foldl (\a b->"["++a++","++b++"]") "0" ["1","2","3"] "[[[0,1],2],3]"
一応出来たけど、Rubyの簡潔さに負けてるのが悔しい。
追記
データ型を定義した場合
data Sexp a = Atom a | List (Sexp a) (Sexp a) deriving Show main = print $ foldl List (Atom 0) (map Atom [1,2,3]) List (List (List (Atom 0) (Atom 1)) (Atom 2)) (Atom 3)
derivingでついてくるshowの出力だとちょっと見にくい。
あと、入力データ型を変更する(Atomをつける)のが面倒。