読者です 読者をやめる 読者になる 読者になる

『関数プログラミング入門 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

こうかもしれない。
っていうか、こうやった場合、fxy が渡されて、簡約されて 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、この結果はカリー化されていることになる。
xy は結果の関数の引数として使われる。

また、上記の簡約した結果を uncurry に渡すときには:

uncurry (curry f)

となり、この式を簡約した結果は:

\(x, y) -> \x y -> f (x, y)

となるので、uncurry の引数 f 以降は (x, y) となるだろう。
上記の結果もまたカリー化されているため:

uncurry (curry f)

は:

f (x, y)

と等しい。(多分これは全ての xy について等しい((と思う。だって型とか考えてないんだもん)))
ということで uncurry は:

uncurry f (x, y) = f x y

である。

先ほどの uncurrycurry を逆にした以下の式においても:

   curry (uncurry f)
=> curry (\(x, y) -> f x y)
=> \x y -> \(x, y) -> f x y

となり:

f x y

と等しい。

ということで、示せた。
(*゚∀゚) シメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタシメセタ

*1:多分

*2:混乱しています。

*3:まだ混乱中

*4:ここでもまだ混乱しています

*5:いや、できねーよwwwwwww

*6:冷静になってきた