テストステ論

高テス協会会長が, テストステロンに関する情報をお届けします.

Functorを試す

最近, 仕事の都合で, 関数型プログラミングが出来るようになりたい熱が再燃しています. データベースと関数型プログラミングはお隣さんのようですね. 興味を持ったことをちょっとずつまとめていきましょう.

通称H本ではMonadを説明するために, Functor, Applicative, Monadと順を追って説明するスタイルをとっています. まずはFunctorを試してみましょう.

Prelude Control.Applicative Control.Monad> :i Functor
class Functor f where
  fmap :: (a -> b) -> f a -> f b
  (<$) :: a -> f b -> f a
    -- Defined in `GHC.Base'
instance Functor Maybe -- Defined in `Data.Maybe'
instance [safe] Functor (Either a)
  -- Defined in `Control.Monad.Instances'
instance [safe] Functor ((->) r)
  -- Defined in `Control.Monad.Instances'
instance [safe] Functor ((,) a)
  -- Defined in `Control.Monad.Instances'
instance Functor ZipList -- Defined in `Control.Applicative'
instance Monad m => Functor (WrappedMonad m)
  -- Defined in `Control.Applicative'
instance Functor (Const m) -- Defined in `Control.Applicative'
instance Functor  -- Defined in `GHC.Base'
instance Functor IO -- Defined in `GHC.Base'

H本にも書いてありますが, 関数もFunctorです. 試してみましょう.

Prelude Control.Applicative Control.Monad> :t fmap (*2) (+5)
fmap (*2) (+5) :: Num b => b -> b
Prelude Control.Applicative Control.Monad> fmap (*2) (+5) $ 2
14

関数合成がされていることが分かりました. 不思議ですが, 受け入れる他ありません.

Functorの関数のうち, (<$)が気になります. 型はa -> f b -> aです. このままでは何のことか分かりません. 試してみましょう.

Prelude Control.Applicative Control.Monad> 1 <$ [100]
[1]
Prelude Control.Applicative Control.Monad> 1 <$ 
[]
Prelude Control.Applicative Control.Monad> 1 <$ [()]
[1]
Prelude Control.Applicative Control.Monad> 1 <$ Just 3
Just 1
Prelude Control.Applicative Control.Monad> 1 <$ Just '3'
Just 1

実際にやってみると分かります. (<$)を自分で実装してみましょう.

Prelude Control.Applicative Control.Monad> let a `myFun` f = fmap (const a) f
Prelude Control.Applicative Control.Monad> :t myFun
myFun :: Functor f => b -> f a -> f b
Prelude Control.Applicative Control.Monad> 1 `myFun` Just '3'
Just 1

myFunのfがFunctorの制約を受けていることも推論してくれています. さすがに賢いです.

ところでこれはHaskellライブラリの設計思想なのでしょうか?fmap (const a) fを省くためだけに, (<$)という謎めいた記号を導入して, 将来の衝突を歓迎しようとするのは. あまり好きではありませんが, せっかくきっかけを掴んだ関数型言語なので, このまま勉強していきます. 最近はLand of Lispという本が出て, Lisp面白いのか?と思ってちょこっと立ち読みしてみたけど, 全く好きそうになれなかった. Haskellが実らなかったら関数型は一生縁がなさそう.

ちなみに, H本H本と言ってるのは, 別にいかがわしい本ではなく,

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!

のことです. Haskellの本が略されてH本になるのが, プログラマの感覚のようです. 本当にHな本なのかどうかは自分で読んで確かめましょう.