Created
May 15, 2014 12:13
-
-
Save naoto-ogawa/e39989551799c124a2a2 to your computer and use it in GitHub Desktop.
Exception Monado
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- | |
-- Excerpt from Monads for functional programming | |
-- http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf | |
-- | |
-- 2.1 Variation zero: The basic evaluator | |
-- | |
data Term = Con Int | Div Term Term | |
eval :: Term -> Int | |
eval (Con a) = a | |
eval (Div t v) = div (eval t) (eval v) | |
answer :: Term | |
answer = Div (Div (Con 1972) (Con 2)) (Con 23) | |
err :: Term | |
err = Div (Con 1) (Con 0) | |
-- 2.2 Variation one: Exceptions | |
-- | |
data M a = Raise Exception | Return a deriving (Show) | |
type Exception = String | |
eval1 :: Term -> M Int | |
eval1 (Con a) = Return a | |
eval1 (Div t v) = case eval1 t of | |
Raise e -> Raise e | |
Return a -> case eval1 v of | |
Raise e -> Raise e | |
Return b -> if b==0 | |
then Raise "divide by zero (eval1)" | |
else Return (div a b) | |
-- 2.7 Variation one, revisited: Exceptions | |
-- | |
unit :: a -> M a | |
unit a = Return a | |
bind :: M a -> (a -> M b) -> M b | |
bind m k = case m of | |
Raise e -> Raise e | |
Return a -> k a | |
raise :: Exception -> M a | |
raise e = Raise e | |
eval2 :: Term -> M Int | |
eval2 (Con a) = unit a | |
eval2 (Div t v) = (eval2 t) `bind` λa -> eval2 v `bind` λb -> unit (div a b) | |
eval2' :: Term -> M Int | |
eval2' (Con a) = unit a | |
eval2' (Div t v) = (eval2' t) `bind` λa -> eval2' v `bind` λb -> if b == 0 then raise "divide by zero (eval2')" else unit (div a b) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment