我收到与我尝试创建的类型类相关的编译时错误。
我的程序:
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”属于 Zoo 类型类,因此应该支持“tiger”方法。
(tiger x) 属于“Tiger”类型类,由“tiger”方法的签名标记。
(tigerWeight (tiger x)) 因此应该能够应用,并且已知是“Ord”类的成员,如“tigerWeight”方法的签名所标记。
最佳答案
'x' and 'y' are in the Zoo typeclass, and therefore should support the 'tiger' method
他们这样做,但不知道您想要Tiger
类型类的哪个居民。如果我们查看 tiger
的完整类型签名,
tiger :: (Zoo a, Tiger t) => a -> t
我们可以看到 a
将由您给 tiger
的参数推导出来,但是 t
会是什么?需要有一个特定的实例(你没有),并且它需要明确。
(tiger x) is in the 'Tiger' typeclass, as marked by the 'tiger' method's signature.
同样,没有 Tiger
的实例。或者,用 OO 术语来说,只有接口(interface),但没有实现该接口(interface)的东西。
(tigerWeight (tiger x)) therefore should be able to be applied, and is known to be a member of the 'Ord' class, as marked by the 'tigerWeight' method's signature.
Ord
类型类相当大。您必须指定您想要的 实例。不清楚您想要哪一个,因为它们都支持 >
。
将其与 read::(Read a) => String -> a
进行比较。只要您不指定 a
,就不清楚应该如何解析字符串。
read "1" :: Int
会起作用,但是
read "1" :: [Int]
应该会失败。需要做出这个选择。
顺便说一句,没有写 tiger::Ord a => a -> o
的明智方法,因为你不能创建任意的 Ord
值。
话虽这么说,但您是从错误的角度来解决这个问题的。 老虎
是一种非常特殊的动物。不需要 typeclass
:
data Tiger = ...
然后,您可以编写一个返回实际重量的完全正常的函数:
type Weight = Int
tigerWeight :: Tiger -> Weight
tigerWeight t = ...
data Zoo = ...
tiger :: Zoo -> Tiger
关于haskell - 无法推断因使用 ‘>’ 而产生的 (Ord a0),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40624579/