データ構成子とか関数合成とか
リストを引数として受け取り、head関数を適用した後Foo型構成子に放りこんで返すheadFoo関数を考えます。
module Main where data Foo a = Foo a deriving Show headFoo a = Foo (head a)
ここで、データ構成子Fooは「a -> Foo a」という関数と見なせるので、次のように書くことができます。
headFoo a = Foo $ head a
ところで、head関数が「[a] -> a」な事を考えると、この二つはドット演算子「(.) :: (b -> c) -> (a -> b) -> a -> c」で合成できそうです。
headFoo a = (Foo.head) a
が、コンパイルしようとしたら怒られました。
$ ghci Main.hs GHCi, version 6.12.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. [1 of 1] Compiling Main ( Foo.hs, interpreted ) Foo.hs:6:13: Not in scope: `Foo.head' Failed, modules loaded: none.
次のように、普通に関数にすれば問題無いので、しばらく何がいけないのか解らなかったのですが・・・
headFoo a = (foo.head) a where foo a = Foo a
エラーメッセージを見てみると「Fooモジュールのhead関数が見つからないよ」
と言っているようなので、どうやらFooが大文字で始まっている事が原因みたいです。
なので、スペースを開けて・・・
headFoo a = (Foo . head) a
こうすればOKですね。