packages feed

hermit-0.3.0.0: examples/fib-tuple/Fib.hs

module Main where

-- so we can fix-intro
import Data.Function (fix)

import Prelude hiding ((+))

data Nat = Z | S Nat

(+) :: Nat -> Nat -> Nat
Z      + n = n
(S n') + n = S (n' + n)

fromInt :: Int -> Nat
fromInt 0 = Z
fromInt i | i < 0 = error "fromInt negative"
          | otherwise = S (fromInt (i-1))

toInt :: Nat -> Int
toInt Z = 0
toInt (S n) = succ (toInt n)

-- original fib definition
fib :: Nat -> Nat
fib Z = Z
fib (S Z) = S Z
fib (S (S n)) = fib (S n) + fib n

-- goal:
-- fib' = fst work
--   where work Z = (Z, S Z)
--         work (S n) = let (x,y) = work n
--                         in (y,x+y)

wrap :: (Nat -> (Nat, Nat)) -> Nat -> Nat
wrap h n = fst (h n)

unwrap :: (Nat -> Nat) -> Nat -> (Nat, Nat)
unwrap h n = (h n, h (S n))

main :: IO ()
main = print $ toInt $ fib (fromInt 30)