[英]Couldn't match expected type ‘Bool’ with actual type ‘Char -> Bool´
[英]Couldn't match expected type ‘(Char, Bool) -> Bool’ with actual type ‘Char’
我正在學習“在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
編譯此代碼時,出現以下錯誤。
tautology_checker.hs:26:23: error:
• Couldn't match expected type ‘(Char, Bool) -> Bool’
with actual type ‘Char’
• In the first argument of ‘find’, namely ‘x’
In the expression: find x s
In an equation for ‘eval’: eval s (Var x) = find x s
|
26 | eval s (Var x) = find x s
|
我已經檢查了拼寫糾正和錯字。 這似乎是正確的。
我的代碼在這里 。
請幫助我如何解決此錯誤。
似乎您無意中使用了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 xs
:
lookup :: Eq a => a -> [(a, b)] -> Maybe b
與fromJust
類的fromJust
(當未綁定變量時拋出錯誤)相結合,例如fromJust (lookup xs)
。 您還可以使用諸如find' xs = fromMaybe (error ("unbound variable '" ++ [x] ++ "'")) (lookup xs)
fromMaybe False
find' xs = fromMaybe (error ("unbound variable '" ++ [x] ++ "'")) (lookup xs)
獲取更詳細的錯誤消息,或者使用fromMaybe False
(假定未綁定變量)是False
),使用fromMaybe
的Data.Maybe
。
最終在您的代碼中使用的函數find
來自Data.List
並具有簽名find :: (a -> Bool) -> [a] -> Maybe a
Data.List
find :: (a -> Bool) -> [a] -> Maybe a
。 此函數嘗試查找給定列表中與給定謂詞匹配的元素。
但是,從在您的代碼中使用此函數的方式來看,您似乎假設簽名find :: k -> Assoc kv -> 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
是局部的 :當給定的關聯列表不包含給定的鍵時,它不知道返回什么。 為了使其總計,需要返回Maybe v
而不是僅返回v
。 只是要記住一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.