朝カットに行って髪を切ってもらっている間、タイトルのようなことを考えていた。
Prelude Control.Arrow> :i (->) data (->) a b -- Defined in `GHC.Prim' Prelude Control.Arrow> :k (->) (->) :: * -> * -> *
であり、(->)は型として定義されている。すごいHaskell(p.232)の言葉を借りれば、適用しろという文脈の着いた型と考えればいいんだろう。
部分適用((->) r)のfmapは(.)なので関数合成なんだが、そういえばArrowか?などとControl.Arrowを探索しはじめた。
Prelude Control.Arrow> :i (.) (.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in `GHC.Base' infixr 9 . Prelude Control.Arrow> :i (>>>) (>>>) :: Control.Category.Category cat => cat a b -> cat b c -> cat a c -- Defined in `Control.Category' infixr 1 >>> Prelude Control.Arrow> :i (<<<) (<<<) :: Control.Category.Category cat => cat b c -> cat a b -> cat a c -- Defined in `Control.Category' infixr 1 <<<
というわけで、(.)と(<<<)は同等のものかな。
(.) :: (b -> c) -> (a -> b) -> a -> c
これは部分適用((->) r)を使えば
(b -> c) -> ((->) a b) -> ((->) a c)
結局(->)をcatに書き換えれば同じ物ができる。そういうあたりから考えるとArrowは関数合成を拡張(一般化?)したものと考えればいいのかなぁ。
とか考えていくうちに関数型の値コンストラクタって一体なんじゃろかねーという疑問が湧いてくるわけで。
14章で状態付きの計算をやったときとかのStateモナドはrunStateで計算をはしらせたけど、関数型はそういうのがないからなぁ、適用しろっていう文脈を持った型なのに、じゃぁどのタイミングで適用すんのよ?とよく分からなくなってきた。
暗黙的な何かなのか、それともそもそも自分の理解がどこか間違っているのか?
120611 追記
値コンストラクタと型コンストラクタをきちんと理解してなかった。型コンストラクタの型変数は引数として取るものだと思っていたが、単に型変数を表しているだけなのね。
data Maybe a = Nothing | Just a -- Defined in `Data.Maybe' data Either a b = Left a | Right b -- Defined in `Data.Either'
なんだけど
read :: Read a => String -> a
見たら、なんか間違っていたと理解した。
それから、RWHのp.228
type InfoP a = FilePath -> Permissions -> Maybe Integer -> ClockTime -> a