[英]Could not deduce (Ord a0) arising from a use of ‘>’
我收到与我要创建的类型类相关的编译时错误。
我的程序:
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'和'y'在Zoo类型类中,因此应支持'tiger'方法
他们可以,但是您不知道想要哪个 Tiger
类型的居民。 如果我们看一下tiger
的完整类型签名,
tiger :: (Zoo a, Tiger t) => a -> t
我们可以看到, a
会被你给的说法可以推断tiger
,但究竟会t
呢? 需要有一个特定的实例(您没有),并且它必须是明确的。
(tiger x)是“ Tiger”类型类,由“ tiger”方法的签名标记。
同样,没有Tiger
实例。 或者,用OO术语来说,只有接口,而没有实现该接口的东西。
(tigerWeight(tiger x))因此应该能够应用,并且已知是“ Ord”类的成员,如“ tigerWeight”方法的签名所标记。
Ord
类型类非常大。 你必须指定你想要的实例。 目前尚不清楚,您想要哪一个,因为它们都支持>
。
比较一下,以read :: (Read a) => String -> a
。 只要您不指定a
,就不清楚如何解析字符串。
read "1" :: Int
会工作,但是
read "1" :: [Int]
应该失败。 该选择需要完成。
顺便说一句,因为您无法创建任意Ord
值,所以没有写Sensilbe的方法来编写tiger :: Ord a => a -> o
a- tiger :: Ord a => a -> o
。
话虽这么说,但您从错误的角度来解决这个问题。 Tiger
是一种非常特殊的动物。 不需要typeclass
:
data Tiger = ...
之后,您可以编写一个完全正常的函数来返回实际重量:
type Weight = Int
tigerWeight :: Tiger -> Weight
tigerWeight t = ...
data Zoo = ...
tiger :: Zoo -> Tiger
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.