如何强制执行函数然后在haskell中返回一个简单的东西

时间:2015-01-13 20:11:35

标签: parsing haskell parsec

所以我正在创建自己的原始shell语言解析器,我想我会创建我的命令(例如cd)表达式,这样我就可以留出一些空间让它们返回值。

现在我已经制作了某种解析器,并且在我的声明消费者中有一个裸露的表达式。

我希望你能为我提供完整的代码。这是有问题的部分:

-- it has other patterns...
makeStatement :: Statement -> VarTable -> Maybe VarTable
makeStatement (Exp exp) vt = ??? 
makeStatement (If ..........
...

data Expression = Val   Int
                | Booly  Bool
                | Var   String
                | Cmd String [String]
                  deriving (Show)

data Statement = Assignment String Expression
               | If Expression Statement
               | IfElse Expression Statement Statement
               | Exp Expression
                deriving (Show)
eval :: VarTable -> Expression -> Maybe Int

所以我想强制执行exp,以防它是Cmd但返回它开始时的相同vt。

1 个答案:

答案 0 :(得分:4)

首先,您可能需要一些复合类型来表示表达式可以返回的三种可能类型。 像

这样的东西
data Value = Number Int | Boolean Bool | String String | Unit

Unit表示不返回任何内容的表达式。 现在,由于表达式中的某些可能会产生副作用,因此您肯定必须将所有内容包装到IO中。有没有纯表达式并不重要,因为编译器不知道哪一个是。

eval :: VarTable -> Expression -> IO Value

现在,您的makeStatement(类似于runStatement可能是一个更好的名字)看起来像这样

makeStatement :: Statement -> VarTable -> IO VarTable
makeStatement (Exp exp)    vt = eval exp >> return vt
makeStatement (If cond th) vt = do
    c <- eval cond
    case c of
        Boolean True -> makeStatement th vt
        _            -> return vt --maybe handle the case where c isn't even Boolean
...

通过此设置,您可以看到我们可以做我猜想你想要的事情。 eval表达式,然后丢弃它的结果,只返回VarTable不变。