星期二, 3月 23, 2010

Haskell Practice - Natural Number

其實就照著書上的教學盡量自己推然後寫,大概是看了 fold fusion ,直觀意義大概就是直接代入後可以少一層,然而這樣子做的好處在 function compose 上可能會少一些動作吧。這篇大概是做個紀錄。不過對我自己而言,做這個練習算是讓我體會到很多事,所有的事都可以依靠簡單的元素來完成時,真的是一件很漂亮的事 !!


data Nat = Zero | Succ Nat
    deriving(Show)

createNat :: Integer -> Nat
createNat i = createNat' i Zero

createNat' :: Integer -> Nat -> Nat
createNat' 0 n = n
createNat' i n = createNat' (i-1) (Succ n)

plusNat :: Nat -> Nat -> Nat
plusNat m Zero = m
plusNat m (Succ n) = Succ (m `plusNat` n)

multNat :: Nat -> Nat -> Nat
multNat m Zero = Zero
multNat Zero n = Zero
multNat (Succ m) (Succ n) = (multNat (Succ m) n) `plusNat` (Succ m)

divNat :: Nat -> Nat -> Nat
divNat (Succ m) Zero = undefined
divNat Zero _ = Zero
divNat (Succ m) (Succ n)
    | (Succ m) == (Succ n) = Succ Zero
    | (Succ m) < (Succ n) = Zero
    | (Succ m) > (Succ n) = (Succ Zero) `plusNat` (divNat ((Succ m) `subNat` (Succ n)) (Succ n))

exponNat :: Nat -> Nat -> Nat
exponNat m Zero = (Succ Zero)
exponNat (Succ m) (Succ n) = (exponNat (Succ m) n) `multNat` (Succ m)

instance Eq Nat where
    Zero == Zero = True
    Zero == Succ n = False
    Succ m == Zero = False
    Succ m == Succ n = (m==n)

    Zero /= Zero = not(Zero == Zero)
    Zero /= Succ n = True 
    Succ m /= Zero = True 
    Succ m /= Succ n = not(m==n)

instance Ord Nat where
    Zero < Zero = False
    Zero < Succ n = True
    Succ m < Zero = False
    Succ m < Succ n = (m= Zero = True 
    Zero >= Succ n = False 
    Succ m >= Zero = True 
    Succ m >= Succ n = not(m Zero = False
    Zero > Succ n = False 
    Succ m > Zero = True 
    Succ m > Succ n = (m>n)
    
    Zero <= Zero = True 
    Zero <= Succ n = True 
    Succ m <= Zero = False 
    Succ m <= Succ n = not(m>n)

    max m n = if m > n then m else n
    min m n = if m < n then m else n

subNat :: Nat -> Nat -> Nat
subNat m Zero = m
subNat (Succ m) (Succ n) 
    | (Succ m) < (Succ n) = undefined
    | otherwise = subNat m n

factNat :: Nat -> Nat
factNat Zero = Succ Zero
factNat (Succ m) = (Succ m) `multNat` (factNat m)

fibNat :: Nat -> Nat
fibNat Zero = Succ Zero
fibNat (Succ Zero) = Succ Zero
fibNat (Succ (Succ m)) = (fibNat (Succ m)) `plusNat` (fibNat m)

infinity :: Nat
infinity = Succ infinity


---
不知道這篇會不會破壞版面 XD。

沒有留言: