Haskell クラス型とFunctor型クラスを学習する

個人開発したアプリの宣伝
目的地が設定できる手帳のような使い心地のTODOアプリを公開しています。
Todo with Location

Todo with Location

  • Yoshiko Ichikawa
  • Productivity
  • Free

スポンサードリンク

クラス型

classキーワードを使用して定義する。EqOrdはクラス型となり、データ型はクラス型を指定することでクラス型のインスタンスとして振舞うことができる。

クラス型はオブジェクト指向言語でいうところのインターフェースのように、インスタンスが持つ関数の型を定義することができる。


クラス型の定義

クラス型YesNoはa型を引数に取りBool型を返す関数インターフェースを提供する。

class YesNo a where
  yesno :: a -> Bool


クラス型のインスタンス

Int型とList型をYesNoクラスのインスタンスとして振る舞えるようにする。

instance YesNo Int where
  yesno 0 = False
  yesno _ = True

instance YesNo [a] where 
  yesno [] = False
  yesno _ = True
ghci> yesno []
False
ghci> yesno (1::Int)
True
ghci> yesno (0::Int)
False

データ型定義時にクラスインスタンスとする場合、derivingでクラス型を与えることで与えられたクラスのインスタンスとして振る舞える。


Functor型クラス

型コンストラクタMaybeListに対する型クラス。中に入った型に作用した後、同じ型コンストラクタに包んで返す関数を定義する。

class Functor f where
  fmap :: (a -> b) ->  f a -> f  b

この時、fは型コンストラクタなので型コンストラクタに包まれたa型をb型に変換して、同じ型コンストラクタに包んだb型を返すという風に読める。

イメージはこんな感じ。

ghci> [ show x | x <- [1,2,3]]
["1","2","3"]


Maybeのfmap

Maybeも型コンストラクタなのでFunctor型のインスタンスとなる。同じものに包まれて、中身の型に関数が作用しているのがわかる。

ghci> fmap (*2) $ Just 1
Just 2
ghci> fmap (*2) $ Nothing 
Nothing
ghci> fmap (show) $ Just 1
Just "1"