interpret Parigot's lambda-mu calculus in Haskell

后端 未结 3 1340
礼貌的吻别
礼貌的吻别 2021-02-06 04:46

One can interpret the lambda calculus in Haskell:

data Expr = Var String | Lam String Expr | App Expr Expr

data Value a = V a | F (Value a -> Value a)

inter         


        
3条回答
  •  隐瞒了意图╮
    2021-02-06 04:54

    How about something like the below. I don't have a good idea on how to traverse Value a, but at least I can see it evaluates example n into MuV.

    import Data.Maybe
    
    type Var = String
    type MuVar = String
    
    data Expr = Var Var
              | Lam Var Expr
              | App Expr Expr
              | Mu MuVar MuVar Expr
              deriving Show
    
    data Value a = ConV a
                 | LamV (Value a -> Value a)
                 | MuV (Value a -> Value a)
    
    type Env a = [(Var, Value a)]
    type MuEnv a = [(MuVar, Value a -> Value a)]
    
    varScopeErr :: Var -> Value a
    varScopeErr v = error $ unwords ["Out of scope λ variable:", show v]
    
    appErr :: Value a
    appErr = error "Trying to apply a non-lambda"
    
    muVarScopeErr :: MuVar -> (Value a -> Value a)
    muVarScopeErr alpha = id
    
    app :: Value a -> Value a -> Value a
    app (LamV f) x = f x
    app (MuV f) x = MuV $ \y -> f x `app` y
    app _ _ = appErr
    
    eval :: Env a -> MuEnv a -> Expr -> Value a
    eval env menv (Var v) = fromMaybe (varScopeErr v) $ lookup v env
    eval env menv (Lam v e) = LamV $ \x -> eval ((v, x):env) menv e
    eval env menv (Mu alpha beta e) = MuV $ \u ->
      let menv' = (alpha, (`app` u)):menv
          wrap = fromMaybe (muVarScopeErr beta) $ lookup beta menv'
      in wrap (eval env menv' e)
    eval env menv (App f e) = eval env menv f `app` eval env menv e
    
    example 0 = App (App t (Var "v")) (Var "w")
      where
        t = Lam "x" $ Lam "y" $ Mu "delta" "phi" $ App (Var "x") (Var "y")
    example n = App (example (n-1)) (Var ("z_" ++ show n))
    

提交回复
热议问题