以下Haskell代码在最后一行抱怨,当我试图检查表达式是否评估形式为Cons _ _时。 Haskell的错误信息是:“表达式上下文中的模式语法:_” - 我想知道的是 - 有没有办法完成我想要做的事情?我似乎要做的是在运行时检查表达式的类型,从我读过的内容可能意味着我可以更好地编程?但是,由于我是初学者,我不知道这是不是我在做什么,特别是因为我在过去一小时内一直试图这样做。
data Val = Num Int | Nil | Cons Val Val
deriving (Eq, Show, Read)
interpret_expr :: Prog -> Vars -> Expr -> Val
interpret_expr _ _ (Isnum NilE) = Num 0
interpret_expr _ _ (Isnum (ConsE _ _)) = Num 0
interpret_expr _ _ (Isnum (NumE _)) = Num 1
interpret_expr prog vars (Isnum expr)
| interpret_expr prog vars expr == Nil = Num 0
| interpret_expr prog vars expr == Cons _ _ = Num 0
| otherwise = Num 1
答案 0 :(得分:8)
interpret_expr prog vars (Isnum expr)
| interpret_expr prog vars expr == Nil = Num 0
| interpret_expr prog vars expr == Cons _ _ = Num 0
| otherwise = Num 1
您对警卫的使用无效。您不能将函数(此处为(==)
函数)应用于模式。也就是说,您无法比较(使用Eq
类型类)某些内容和Cons _ _
。您需要再次进行模式匹配,并且可以使用case .. of
:
interpret_expr prog vars (Isnum expr) = case interpret_expr prog vars expr of
Nil -> Num 0
Cons _ _ -> Num 0
_ -> Num 1
答案 1 :(得分:5)
检查值是否属于特定构造函数是常见的事情。很多时候,您会在表单中看到一个手写的片段:
isCons (Cons _ _) = True
isCons _ = False
它将用作:
| isCons (interpret_expr prog vars expr) = Num 0
这很常见,各种源代码重写工具都会添加is[Some Constructor]
个函数(例如:derive
和DriFT
)。我偏爱模板haskell解决方案(因为它们不需要运行外部工具,不是因为TH非常干净或稳定)。如果您安装了derive
库,那么您的代码可能如下所示:
import Data.Derive.Is
import Data.DeriveTH
import Language.Haskell.TH
data Val = ...
deriving (Eq, Ord, Show)
$(derive makeIs ''Val)