Haslellその5

ラムダ計算続き

g1 = \x y -> x + y
g2 = \x -> map (g1 1) x
g3 = \f -> map f [1..5]         -- functional argument
{-
    g1 2 3 -- 5
    g2 [1..5] -- [2,3,4,5,6]
    g3 (g1 1) -- [2,3,4,5,6]
-}
*Sample1> :type g2
g2 :: [Integer] -> [Integer]
*Sample1> :type g3
g3 :: (Integer -> b) -> [b]

g2はg1の型制約を受けて[Integer]になる。
一方、g3は[b]になるので、こんな↓のもg3に渡せる。

g4 = \x -> "B"
{-
    g3 g4 -- ["B","B","B","B","B"]
-}

さらにラムダの配列を扱う。

f1 = \x -> x+1
f2 = \x -> x^2
h1 = [f1,f2]
h2 [] as = []
h2 (f:fs) as = map f as : h2 fs as

{-
    h2 h1 [1..5] -- [[2,3,4,5,6],[1,4,9,16,25]]
-}
*Sample1> :type h1
h1 :: [Integer -> Integer]
*Sample1> :type h2
h2 :: [a -> b] -> [a] -> [[b]]

ふーむ。[a -> b]なんて型が許されるのなら、

h0 = [f1,g4]

ってどう?

    Probable fix: add an instance declaration for (Num [Char])
    In the second argument of `(+)', namely `1'
    In a lambda abstraction: \ x -> x + 1
    In the definition of `f1': f1 = \ x -> x + 1

怒られちゃった、しかもf1の定義で。
[a -> b]は[a -> _]ってわけじゃあないのね。
そもそも[a -> _]なんて許されない。

はは、ここ↓に書いてるな。
http://www.sampou.org/haskell/tutorial-j/goodies.html

”多相型の表現式は本質的には、型の族をあらわすものです”

ラムダ抽象と関数の同等性

f_plus1 x y = x + y
f_plus2 = \ x y -> x + y

http://www.sampou.org/haskell/tutorial-j/functions.html

”等式を使わずにラムダ抽象 (lambda abstraction) を使って無名関数を定義することができます”
”一般に x があって、その型が t1 で、exp の型が t2 である場合、\x->exp の型はt1->t2 ということになります。 ”

…深く考えるのはやめよう。

中間演算子と関数の同等性

http://www.sampou.org/haskell/tutorial-j/functions.html

”中置演算子はまさに関数ですから、関数と同じように、部分適用が可能です。”
”中置演算子を関数値に変換できましたが、それでは、その逆は可能なのでしょうか。可能です。関数値をバッククウォートで括るだけです。”

f_plus3 = \ x y -> (+) x y
f_plus4 = (+)
*Sample1> f_plus4 2 3
5
*Sample1> 2 `f_plus4` 3
5

うーむ、自分なりのスタイルを持たないとわけ分からなくなりそう。
それとも…スタイルに縛られないのもポストモダンプログラミングの良さなのか?