问题描述
我正在尝试建立一个数据结构,它是 lambda 演算的扩展,以允许加法和减法。我正在尝试创建一个称为 AE 的结构,它可以将 Lit 作为其本身,也可以计算加法和减法。我收到的错误说明如下:
无效的类型签名:Lit :: ...
应该是表单变量::类型
点燃 :: Int -> AEp>
我对这个数据结构的声明有什么问题?
{-# Language GADTs #-}
data AE where
Lit :: Int -> AE
Add :: Int -> Int -> AE
Sub :: Int -> Int -> AE
deriving (Show)
eval :: AE -> Maybe Int
eval (Lit n) = Just n
eval (Add n1 n2) = n1 + n2
eval (Sub n1 n2) = do
if(n1<n2) then return nothing
else return n1 - n2
解决方法
您需要缩进 where
子句下的数据构造函数,因此:
{-# Language GADTs #-}
data AE where
Lit :: Int -> AE
Add :: Int -> Int -> AE
Sub :: Int -> Int -> AE
否则,您将定义一个类型 AE
没有任何数据构造函数。如果缩进,则它是 data AE where
块的一部分,因此您定义了三个数据构造函数。
您的 eval
函数还包含一个 do
块。尽管 Maybe
是 Monad
的一个实例,但您不能像这样使用 do
表示法。尤其是 return nothing
部分在这里是有问题的。对于 Monad
实例 Maybe
,return = Just
,这意味着 return Nothing
将构造一个 Maybe (Maybe a)
。您可以使用警卫来定义警卫应该“开火”的条件。
另一个问题是n1 + n2
。这具有类型 Int
,而不是 Maybe Int
,因此您需要将其包装到 Just
数据构造函数中:
eval :: AE -> Maybe Int
eval (Lit n) = Just n
eval (Add n1 n2) = Just (n1 + n2)
eval (Sub n1 n2)
| n1 < n2 = Nothing
| otherwise = Just (n1 - n2)