Haskell 不能';t匹配预期类型‘;(Char,Bool)——>;布尔’;实际类型为‘;Char’;
我正在学习本书第8章中的重言式检查器部分 有一段代码提到Haskell 不能';t匹配预期类型‘;(Char,Bool)——>;布尔’;实际类型为‘;Char’;,haskell,Haskell,我正在学习本书第8章中的重言式检查器部分 有一段代码提到 eval :: Subst -> Prop -> Bool eval _ (Const b) = b eval s (Var x) = find x s eval s (Not p) = not (eval s p) eval s (And p q) = eval s p && eval s q eval s (Imply p q) = eval s p <= eval s q 我已经检查了拼写更正
eval :: Subst -> Prop -> Bool
eval _ (Const b) = b
eval s (Var x) = find x s
eval s (Not p) = not (eval s p)
eval s (And p q) = eval s p && eval s q
eval s (Imply p q) = eval s p <= eval s q
我已经检查了拼写更正和打字错误。这似乎是正确的
我的密码是
请帮助我如何解决此错误 您似乎无意中使用了Prelude的标准函数
find
,类型为:
Foldable t => (a -> Bool) -> t a -> Maybe a
或者,专门用于列表:
(a -> Bool) -> [a] -> Maybe a
然而,本书希望您使用一些其他的find
函数,可能在本文的其他地方定义,类型如下:
(Eq a) => a -> [(a, b)] -> b
或者,在您的情况下:
Char -> [(Char, Bool)] -> Bool
您给它的第一个参数是x
,它的类型是Char
,但它需要的函数类型是(Char,Bool)->Bool
,因为(Char,Bool)
是列表的元素类型。这就是您得到的类型错误的来源
您可以使用标准功能lookup
替换find x s
:
lookup :: Eq a => a -> [(a, b)] -> Maybe b
与类似于
fromJust
(当变量未绑定时会抛出错误)的内容结合使用,例如fromJust(lookup x s)
。您还可以使用类似于find'xs=fromMaybe(error(“unbound variable'++[x]++“”))(lookup xs)
的内容来获取更详细的错误消息,或者fromMaybe False
(假设未绑定变量为False
),从数据中使用可能可能。可能似乎您无意中使用了Prelude的标准函数查找
,类型为:
Foldable t => (a -> Bool) -> t a -> Maybe a
或者,专门用于列表:
(a -> Bool) -> [a] -> Maybe a
然而,本书希望您使用一些其他的find
函数,可能在本文的其他地方定义,类型如下:
(Eq a) => a -> [(a, b)] -> b
或者,在您的情况下:
Char -> [(Char, Bool)] -> Bool
您给它的第一个参数是x
,它的类型是Char
,但它需要的函数类型是(Char,Bool)->Bool
,因为(Char,Bool)
是列表的元素类型。这就是您得到的类型错误的来源
您可以使用标准功能lookup
替换find x s
:
lookup :: Eq a => a -> [(a, b)] -> Maybe b
与类似于fromJust
(当变量未绑定时会抛出错误)的内容结合使用,例如fromJust(lookup x s)
。您还可以使用类似于find'xs=fromMaybe(error(“unbound variable'++[x]++“”))(lookup xs)
的内容来获取更详细的错误消息,或者fromMaybe False
(假设未绑定变量为False
),使用fromMaybe
from数据。Maybe
最终在代码中使用的函数find
来自数据。List
具有签名find:(a->Bool)->[a]->Maybe a
。此函数尝试查找给定列表中与给定谓词匹配的元素
但是,从代码中使用此函数的方式来看,您似乎假设签名find::k->Assoc k v->v
,其语义是在关联列表中按键定位值。这就是我将如何实现此功能:
find :: Eq k => k -> Assoc k v -> v
find k ((k', v) : _) | k == k' = v
find k (_ : tail) = find k tail
我没有这本书,所以我不能确定,但我的猜测是这本书实际上在更早的地方定义了这个函数,可能是在它定义类型Assoc
本身的同一个地方。您在代码中包含了Assoc
的定义,但忘记了包含find
的定义
还要注意,以这种方式定义的函数find
是局部的:当给定的关联列表不包含给定的键时,它不知道返回什么。为了使其成为总计,它需要返回可能是v
,而不仅仅是v
。需要记住的是。最终在代码中使用的函数find
来自数据。List
具有签名find::(a->Bool)->[a]->可能是a
。此函数尝试查找给定列表中与给定谓词匹配的元素
但是,从代码中使用此函数的方式来看,您似乎假设签名find::k->Assoc k v->v
,其语义是在关联列表中按键定位值。这就是我将如何实现此功能:
find :: Eq k => k -> Assoc k v -> v
find k ((k', v) : _) | k == k' = v
find k (_ : tail) = find k tail
我没有这本书,所以我不能确定,但我的猜测是这本书实际上在更早的地方定义了这个函数,可能是在它定义类型Assoc
本身的同一个地方。您在代码中包含了Assoc
的定义,但忘记了包含find
的定义
还要注意,以这种方式定义的函数find
是局部的:当给定的关联列表不包含给定的键时,它不知道返回什么。为了使其成为总计,它需要返回可能是v
,而不仅仅是v
。只是需要记住一点。事实上,这本书在type Assoc
旁边给出了find函数的定义。我注意到类型Assoc
,但没有查找功能。无论如何,谢谢你的帮助。事实上,这本书在类型Assoc
旁边给出了find函数的定义。我注意到类型Assoc
,但没有查找功能。无论如何,谢谢你的帮助。