我遇到了与我试图创建的类型类相关的编译时错误。
我的节目:
main = print "here"
class Tiger a where
tigerWeight :: (Ord o) => a -> o
class Zoo a where
tiger :: (Tiger t) => a -> t
tigerHeavier :: a -> a -> Bool
tigerHeavier x y =
(tigerWeight (tiger x)) > (tigerWeight (tiger y))
给出了编译错误:
$ ghc zoo
[1 of 1] Compiling Main ( zoo.hs, zoo.o )
zoo.hs:14:5: error:
• Could not deduce (Ord a0) arising from a use of ‘>’
from the context: Zoo a
bound by the class declaration for ‘Zoo’ at zoo.hs:(10,1)-(14,53)
The type variable ‘a0’ is ambiguous
These potential instances exist:
instance Ord Ordering -- Defined in ‘GHC.Classes’
instance Ord Integer
-- Defined in ‘integer-gmp-1.0.0.1:GHC.Integer.Type’
instance Ord a => Ord (Maybe a) -- Defined in ‘GHC.Base’
...plus 22 others
...plus two instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the expression:
(tigerWeight (tiger x)) > (tigerWeight (tiger y))
In an equation for ‘tigerHeavier’:
tigerHeavier x y
= (tigerWeight (tiger x)) > (tigerWeight (tiger y))
zoo.hs:14:6: error:
• Could not deduce (Tiger a1) arising from a use of ‘tigerWeight’
from the context: Zoo a
bound by the class declaration for ‘Zoo’ at zoo.hs:(10,1)-(14,53)
The type variable ‘a1’ is ambiguous
• In the first argument of ‘(>)’, namely ‘(tigerWeight (tiger x))’
In the expression:
(tigerWeight (tiger x)) > (tigerWeight (tiger y))
In an equation for ‘tigerHeavier’:
tigerHeavier x y
= (tigerWeight (tiger x)) > (tigerWeight (tiger y))
zoo.hs:14:32: error:
• Could not deduce (Tiger a2) arising from a use of ‘tigerWeight’
from the context: Zoo a
bound by the class declaration for ‘Zoo’ at zoo.hs:(10,1)-(14,53)
The type variable ‘a2’ is ambiguous
• In the second argument of ‘(>)’, namely ‘(tigerWeight (tiger y))’
In the expression:
(tigerWeight (tiger x)) > (tigerWeight (tiger y))
In an equation for ‘tigerHeavier’:
tigerHeavier x y
= (tigerWeight (tiger x)) > (tigerWeight (tiger y))
这是为什么?似乎所有类型都应该是可以推断的。特别是:
' X'并且' y'在动物园类型类中,因此应该支持“老虎”。方法
(虎x)在老虎'类型,由老虎'标记。方法的签名。
(tigerWeight(tiger x))因此应该能够应用,并且已知是“奥德”的成员。班级,由'tigerWeight'标记。方法的签名。
答案 0 :(得分:4)
' X'并且' y'在动物园类型类中,因此应该支持“老虎”。方法
他们这样做,但不知道你想要的Tiger
类型的居住者 。如果我们查看tiger
的完整类型签名,
tiger :: (Zoo a, Tiger t) => a -> t
我们可以看到a
将由您提供的参数tiger
推断,但t
会是什么?需要有一个特定的实例(你没有),它必须是明确的。
(虎x)在老虎'类型,由老虎'标记。方法的签名。
同样,没有Tiger
的实例。或者,与OO术语说话,只有界面,但不是实现该界面的东西。
因此,应该能够应用(tigerWeight(tiger x)),并且已知它是“奥德”的成员。班级,由'tigerWeight'标记。方法的签名。
Ord
类型类比较大。您必须指定您想要的实例。它不清楚,你想要哪一个,因为它们都支持>
。
将其与read :: (Read a) => String -> a
进行比较。只要您没有指定a
,就不清楚如何解析字符串。
read "1" :: Int
会奏效,但
read "1" :: [Int]
应该失败。这个选择需要做。
顺便说一句,写tiger :: Ord a => a -> o
没有敏感的方法,因为你无法创建任意Ord
值。
话虽如此,你从错误的方面接近这个问题。 Tiger
是一种非常特殊的动物。不需要typeclass
:
data Tiger = ...
之后,您可以编写一个返回实际重量的完全正常的函数:
type Weight = Int
tigerWeight :: Tiger -> Weight
tigerWeight t = ...
data Zoo = ...
tiger :: Zoo -> Tiger