haskell - 无法推断因使用 ‘>’ 而产生的 (Ord a0)

标签 haskell typeclass

我收到与我尝试创建的类型类相关的编译时错误。

我的程序:

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/

相关文章:

Haskell:Num 是如何保存的?

haskell - Haskell 中的欧拉问题——有人能发现我的错误吗

haskell - 在类型族中编写多态函数

haskell - 懒惰的评估如何迫使 Haskell 变得纯粹

haskell - 格雷特函数定义

haskell - 上下文中的约束如何改变 Haskell 中的实例解析

haskell - 带 kind * -> * 的类型类实例的类型参数约束

haskell - 为什么 Sum 和 Product 没有 Enum 实例?

haskell - 访问状态 Monad haskell 中的计数

Haskell 随机数生成