- はじめにMyType1なるタイプを定義する。deriving Showは表示を可能にするためのおまじない
- MyType1はAかBかの2つの実体を持つだけ
- MyType1だけがある世界でも関数は定義できる
- MyType2を加える。MyType1とMyType2とを行き来する関数が定義できる
- MyType3を加える。それはMyType1とMyType2とを引数として取るPとQという2種類の実体を持つ。
- MyType3を引数に取る関数には、Pであること、Qであることを教えつつ、P、Qの中身もちゃんとあることを明示する。P、Qの中にあるMyType1,MyType2などを使って返り値を指定することも出来る
module MyWorld
where
data MyType1 = A | B
deriving Show
myf1 :: MyType1 -> MyType1
myf1 x = case x of
A -> B
B -> A
data MyType2 = X1 | X2 | X3 | X4 | X5 | X6
deriving Show
myf2 :: MyType2 -> MyType1
myf2 x = case x of
X1 -> A
X2 -> A
X3 -> B
X4 -> B
X5 -> B
X6 -> B
myf3 :: MyType1 -> MyType2
myf3 x = case x of
A -> X3
B -> X6
data MyType3 = P MyType1 MyType2
| Q MyType1 MyType2 MyType2
deriving Show
myf4 :: MyType3 -> MyType1 -> MyType2
myf4 (P _ _) x = case x of
A -> X3
B -> X5
myf4 (Q _ _ _) x = case x of
A -> X2
B -> X1
myf5 :: MyType3 -> MyType2
myf5 (P x _) = case x of
A -> X5
B -> X6
myf5 (Q _ _ z) = case z of
X1 -> X5
X2 -> X3
X3 -> X5
X4 -> X3
X5 -> X5
X6 -> X3
stack ghci
:load MyWorld.hs
*MyWorld> :type A
A :: MyType1
*1494231392*MyWorld> :type X1
X1 :: MyType2
*1494231393*MyWorld> :type P
P :: MyType1 -> MyType2 -> MyType3
*1494231394*MyWorld> :type myf1
myf1 :: MyType1 -> MyType1
*1494231395*MyWorld> :type myf2
myf2 :: MyType2 -> MyType1
*1494231396*MyWorld> :type myf3
myf3 :: MyType1 -> MyType2
*1494231397*MyWorld> :type myf4
myf4 :: MyType3 -> MyType1 -> MyType2
*1494231398*MyWorld> :type myf5
myf5 :: MyType3 -> MyType2
*1494231399*MyWorld> myf1 A
B
*1494231400*MyWorld> myf2 X3
B
*1494231401*MyWorld> myf3 B
X6
*1494231402*MyWorld> myf4 (P B X5) A
X3
*1494231403*MyWorld> myf5 (Q A X3 X2)
X3
*1494231404*MyWorld> :type Q A
Q A :: MyType2 -> MyType2 -> MyType3
*1494231405*MyWorld> :type Q A X4
Q A X4 :: MyType2 -> MyType3
*1494231406*MyWorld> :type Q A X4 X2
Q A X4 X2 :: MyType3
*1494231407*MyWorld>