『関数プログラミング入門 Haskellで学ぶ原理と技法』やってみた
問 1.41
f
および g
が以下の型を持つとする:
f :: Integer -> Integer g :: Integer -> (Integer -> Integer)
h
を以下のように定義してみよう:
h :: ... h x y = f ( g x y )
h
に正しい型を割り当てよ:
1.4.1 の回答?
g
は整数値を取って、整数値を取って整数値を返す関数を返す関数を返す関数である。
h
の引数 x
が整数型であることはこのことから自明である*1。
f
が整数値を取って整数値を返す関数であることから、g x y
は (g x) y
っぽいなーと分かる。
y
もどうやら整数値であることが分かったので関数 h
は:
h :: Integer -> Integer -> Integer
という型を持つことが分かる。
ʕ•͡ω•ʔ y の方は g の戻り値に対して渡してるってわけだな
╰( ´◔ ω ◔ `)╯ ん? 実の所、 h も g もおんなじなんじゃね?
ʕ•͡ω•ʔ そんなわきゃねーだろwwww
問 1.4.2
先に定義した関数 delta
の引数をカリー化して、delta (a, b, c)
と書かずに
delta a b c
と書けるようにしたとする。
このカリー化された版の型はどうなっているか。
1.4.2 の回答?
delta :: Float -> Float -> Float
だと思う。
問 1.4.3
log2、loge、log10 のように、数学では様々な底の対数を使う。 底を引数としてとり、その底で対数を計算する関数の正しい型を答えよ。
1.4.3 の回答?
log :: Float -> (Float -> Float)
とかやっておくと:
log2 = log 2
とかできるのでお得!
問 1.4.4
数学の解析学で使う(f の a から b までの)定積分関数に対して適切な型を与えよ。
1.4.4 の回答?
まず定積分関数がなんだかわかっていないものの、多分このような式になりそう:
f a b = ...
なので、こうなるはず:
f :: Float -> Float -> Float
なんか違うかも?
問 1.4.7
カリー化された関数をカリー化されていない版に変換する関数 uncurry
を定義せよ。
すべての x
および y
に対して以下が成り立つことを示せ。
curry (uncurry f) x y = f x y uncurry (curry f) (x, y) = f (x, y)
1.4.7 の回答?
uncurry :: (a -> b -> c) -> ((a, b) -> c) uncurry f x y = f (x, y)
ではあるけど、curry
が間違っているのでは??
ことによったら:
uncurry f (x, y) = f x y
こうかもしれない。
っていうか、こうやった場合、f
に x
と y
が渡されて、簡約されて f x y
の戻り値が返らないの???*2
curry
が:
curry f = \x -> \y -> f (x, y)
だとかって云うならわかるけど、ん?
curry f x y = f (x, y)
は:
curry = \x y = f (x, y)
なんだっけ?*3
というか、我々(1 人しかいないけど)はとんでもない思い違いをしていたのかもしれない*4…………。
引数が全部渡されたとしても、その式を関数呼び出しではなく部分適用として簡約することは可能……っ!!!!
ΩΩΩ<な、なんだってー!?*5
つまり、uncurry
は
uncurry f x y = f x y
という感じ……? に? うーん、これでいいの?
仮に f
がカリー化されていない関数で:
curry f
というように式をおいたとする。この式を簡約した結果は:
\x y -> f (x, y)
となり*6、この結果はカリー化されていることになる。
x
と y
は結果の関数の引数として使われる。
また、上記の簡約した結果を uncurry
に渡すときには:
uncurry (curry f)
となり、この式を簡約した結果は:
\(x, y) -> \x y -> f (x, y)
となるので、uncurry
の引数 f
以降は (x, y)
となるだろう。
上記の結果もまたカリー化されているため:
uncurry (curry f)
は:
f (x, y)
と等しい。(多分これは全ての x
と y
について等しい((と思う。だって型とか考えてないんだもん)))
ということで uncurry
は:
uncurry f (x, y) = f x y
である。
先ほどの uncurry
と curry
を逆にした以下の式においても:
curry (uncurry f)
=> curry (\(x, y) -> f x y)
=> \x y -> \(x, y) -> f x y
となり:
f x y
と等しい。
ということで、示せた。
(*゚∀゚) シメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタ