ふつける:5,6章読んだ
ふつける6章まで読了.5章の,遅延評価の考え方は凄い.関数型言語ならではだなぁと思った(そうでもない?).中でも,最外簡約,グラフ簡約が.こいつぁすげぇや.
6章では色んな型ってのを(今更ながら)学んだのだけども,その途中,ふとzipWithをmapとzipを使って書けるかしらと思ったので,ちょっとやってみました.
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c] zipWith' f x y = map (fs f) $ zip x y where fs f x = f (fst x) (snd x)
fsは結局,置き換えようと思えば
k x = f (g x) (h x)
なんで,なんとか関数結合を使って表せないかなと考えたものの,なんだか訳が分かんなくなったのでやめました.
Preludeの定義を見てみると,
zip = zipWith (,)
なんですね.しかも結局zipWithは再帰定義だし.んじゃzipWithをzipを使って書く,ってすごく効率が悪いんだな.
タプル
タプルを作る時,
(,) a b
と出来るという事を知ったのですが,これもちゃんと型を見てみると
Main> :t (,) (,) :: a -> b -> (a,b) Main> :t (,,) (,,) :: a -> b -> c -> (a,b,c)
と.それじゃこれはどうなる.
Main> :t (,,,,,,,,,,,,,,,,) (,,,,,,,,,,,,,,,,) :: a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> m -> n -> o -> p -> q -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q)
ふおぉ,根性だな.関数定義というより言語仕様って感じだなぁ.
遅延評価
これを考えてる途中,
f = (*) g = (fst) h = (snd) k = (.(.f)) (.g) (.h)
と言うのを書いてたんですが,型を見てみると
Main> :t k k :: (Integer,a) -> (b,Integer) -> Integer
と.
型推論!最外簡約!
追記
b2oxさんの助言により,zipWithがスッキリしました.
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c] zipWith' f x y = map (uncurry f) $ zip x y
Hoogλe,大切にしないと.