私のためのHaskell〜自作タイプだけで作る世界

  • はじめに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
  • これをMyWorld.hsと保存して
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>