On 06/30/2011 08:25 PM, Philipp Schneider wrote:
> On 06/30/2011 02:36 PM, Holger Siegel wrote:
>> Am 29.06.2011 um 23:50 schrieb Philipp Schneider:
>>
>>> Hi cafe,
>>>
>>> in my program i use a monad of the following type
>>>
>>> newtype M a = M (State -> (a, State))
>>>
>>> i use the monad in two different ways. The type variable "a" can be a
>>> pair as in
>>>
>>> interp :: Term -> Environment -> M (Value,Environment)
>>>
>>> and it can be just a value as in
>>>
>>> type Environment = [(Name, Either Value (M Value))]
>> Simple rule: Never return an environment!
>>
>> An environment contains local variable bindings, so no subcomputation will 
>> ever need to return its environment. I don't know anything about the 
>> language your program interprets, but I'm sure that you can rewrite function 
>> interp as
>>
>>   interp :: Term -> Environment -> M Value
>>
>> The structure of the interpreter will become clearer and your problem will 
>> vanish.
>>
> Hello Holger,
>
> I'm giving two lambda interpreters. The first one is a call by value
> interpreter, the second one a call by name interpreter which are
> described in Philip Wadler's paper "The essence of functional
> programming" page 4 and 12. Now my task is to write a lazy lambda
> interpreter. The exercise is more playful than serious since Wadler's
> call by value interpreter is, since written in lazy Haskell, already a
> lazy lambda interpreter. (To get true call by value one would need to
> force evaluations of the arguments with the seq function.)
> For both of Wadler's interpreters the type of the interpertation
> function is:
> interp :: Term -> Environment -> M Value
>
> Now to simulate lazy interpretation i need to do the following: Decide
> is the value I need already evaluated or is it still a computation. In
> the later case I need to evaluate it and save its value in the
> environment. This is the reason I changed the type of the interpretation
> function to:
> interp :: Term -> Environment -> M (Value,Environment)
>
> I appened my full interpreter. If you can find a more elegant way to
> save the newly interpreted values, you are more than welcome to show my
> how to do it.
>
> Cheers,
> Philipp
I forgot to add the interpreter.
{-# LANGUAGE OverlappingInstances #-}

import Prelude hiding (lookup, fail)

import Control.Monad
   
-- Basiswerte

data Value    = WrongAd
              | WrongAp
              | WrongL
              | Num Int
              | Fun (Either Value (M Value) -> M Value)

instance Show Value where
   show WrongAd    = "<wrong add>"      
   show WrongAp    = "<wrong app>"         
   show WrongL    = "<wrong lookup>"   
   show (Num i)  = show i
   show (Fun f)  = "<function>"

-- Terme 

data Term     = Var Name
              | Con Int
              | Add Term Term
              | Lam Name Term
              | App Term Term deriving Show

-- Interpretation der Terme (Lazy evaluation)

interp :: Term -> Environment -> M (Value,Environment)
interp (Var x) e   = lookup x e
interp (Con i) e   = return (Num i,e)
interp (Add u v) e =  do
  (a,e) <- interp u e
  (b,e) <- interp v e
  s <- add a b
  return (s,e)
interp (Lam x v) e  = return (Fun (\m -> (interp v ((x, m):e)) >>= return . fst) , e)
interp (App t u) e  = do
  (f,e) <- interp t e
  a <- (apply f (Right ((interp u e) >>= return . fst)))
  return (a,e)


add :: Value -> Value -> M Value
add (Num i) (Num j) = tick >>= (\() -> return (Num (i+j)))
add a b             = return WrongAd

apply :: Value -> Either Value (M Value) -> M Value
apply (Fun k) a    = tick >>= (\() -> k a)
apply notFun a     = return WrongAp

-- Umgebung

type Environment = [(Name, Either Value (M Value))]
type Name = String

lookup :: Name -> Environment -> M (Value,Environment)
lookup x eComplete = lookup_h x eComplete
  where
    lookup_h x []        = return (WrongL,[])
    lookup_h x e@((y,b):etl) = 
      if x==y then case b of 
        -- schon ausgewertet
        Left a -> return (a,e) 
        -- noch nicht ausgewertet (speichere den ausgewerteten Wert)
        Right a -> (a >>= (\x-> return (x, (y,Left x):eComplete)))
      else lookup_h x etl

-- Lazy-Interpreter zaehlt die Reduktionen (Wadler: Beispiel 9)

type State = Int

newtype M a = M (State -> (a, State))

tick = M (\s -> ((), s+1))


instance (Show a,Show b) => Show (M (a,b)) where
   show (M f) = let ((v,_), s) = f 0 in
     "Value: " ++ show v ++  " Count: " ++ show s

instance Show a => Show (M a) where
   show (M f) = let (v, s) = f 0 in
     "Value: " ++ show v ++  " Count: " ++ show s


instance Monad M where
   return a = M (\s -> (a, s))
   (M m) >>= k = M (\s0 -> let (a, s1) = m s0
                               (M m')  = k a
                           in m' s1
                      ) 
   fail s = error s     -- wird nicht aufgerufen
   
-- Beispiele:

-- test :: Term -> String
test t             = (interp t [])

term0 = (Con 10)
term0' = (Var "x")
term1 = (Add (Con 10) (Con 11))
term2 = (Lam "x" (Add (Var "x") (Con 10)))
term3 = (App term2 (Con 11))
term4 = (Lam "x" (Add (Var "x") (Var "x")))
term5 = (App term4 term1)
term6 = (Lam "x" (Lam "y" (Add (Var "x") (Var "y"))))
term7 = (App term6 (Con 10))
term8 = (App term7 (Con 11))
term7' = (App (Lam "x" (Lam "y" (Add (Var "x") (Var "y"))))
              (Con 10))
term8' = (App (App (Lam "x" (Lam "y" (Add (Var "x") (Var "y"))))
                   (Con 10))
              (Con 11))
term9 = (Lam "x" (Var "x"))
term10 = (App (Lam "x" (Var "x")) (Con 15))
term11 = (Add (Con 10) (Add (Con 11) (Con 5)))
twice = (Lam "f" (Lam "x" (App (Var "f") 
                                (App (Var "f") (Var "x")))))
increm = (Lam "x" (Add (Var "x") (Con 1)))
term12 = (App (App twice increm) (Con 5))

-- Beispiele mit Fehlern:

termE1 = (Add (Var "x") (Con 10))
termE2 = (Add (Con  10) term9)
termE3 = (App (Con 1) (Con 2))
termE4 = (App (App twice (Con 3)) (Con 5))

bot = (App (Lam "x" (App (Var "x") (Var "x")))
       (Lam "x" (App (Var "x") (Var "x"))))
term13 = (App (Lam "x" (Con 1)) bot)
term14 = (Add term13 (Con 7))
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to