我正在尝试为函数类型实现类型类:
{-# LANGUAGE FlexibleInstances #-}
module Match where
import Tokens (Token (..))
class Match a where
match :: (Match b) => a -> [Token] -> Either String b
instance Match (Int -> b) where
match = matchInt
matchInt :: (Match b) => (Int -> b) -> [Token] -> Either String b
matchInt fn (Number i : ts) = match (fn i) ts
matchInt _ _ = Left "missing integer argument"
我在构建时不断收到以下错误,我不明白我做错了什么:
error: [GHC-25897]
• Couldn't match type ‘b1’ with ‘b’
Expected: (Int -> b) -> [Token] -> Either String b1
Actual: (Int -> b) -> [Token] -> Either String b
‘b1’ is a rigid type variable bound by
the type signature for:
match :: forall b1.
Match b1 =>
(Int -> b) -> [Token] -> Either String b1
at src/Match.hs:11:5-9
‘b’ is a rigid type variable bound by
the instance declaration
at src/Match.hs:10:10-25
• In the expression: matchInt
In an equation for ‘match’: match = matchInt
In the instance declaration for ‘Match (Int -> b)’
• Relevant bindings include
match :: (Int -> b) -> [Token] -> Either String b1
(bound at src/Match.hs:11:5)
|
11 | match = matchInt
| ^^^^^^^^
我不想更改类型类以显式引用函数。那是因为我希望能够实现非函数的类型类。 (这个想法是,您可以传递一个类型构造函数来与标记列表一起匹配,它会吐出完全构造的类型或错误)
此错误通常是由类型不匹配引起的。 在您的代码中,定义的 match 函数的类型签名为 (Int-> b)-> [Token]-> Either String b1,而实例中的 matchInt 函数的类型为 (Int-> b)-> [Token ]-> 任一字符串 b. 这里b1和b被视为不同类型的变量,导致类型不匹配错误。 要解决这个问题,需要确保match函数和matchInt函数的类型完全相同,即它们都使用相同类型的变量b。您可能需要检查函数的实现和类型声明,以确保它们在类型上协调一致。