【问题标题】:No instance for (Ord a0) arising from a use of ‘mymerge’没有因使用“mymerge”而产生 (Ord a0) 的实例
【发布时间】:2016-12-19 12:23:17
【问题描述】:

我正在阅读“Haskell 编程”,我正在尝试合并两个排序列表。这是我的代码:

mymerge :: Ord a => [a] -> [a] -> [a]
mymerge xs [] = xs
mymerge [] ys = ys
mymerge (x:xs) (y:ys) | x < y     = x : mymerge xs (y:ys)
                      | otherwise = y : mymerge (x:xs) ys

它适用于所有情况,除非我尝试将测试定义为:

t72 = mymerge [] []

错误是:

No instance for (Ord a0) arising from a use of ‘mymerge’
The type variable ‘a0’ is ambiguous
Relevant bindings include t72 :: [a0] (bound at ch06.hs:109:1)
Note: there are several potential instances:
  instance (Ord a, Ord b) => Ord (Either a b)
    -- Defined in ‘Data.Either’
  instance forall (k :: BOX) (s :: k). Ord (Data.Proxy.Proxy s)
    -- Defined in ‘Data.Proxy’
  instance (GHC.Arr.Ix i, Ord e) => Ord (GHC.Arr.Array i e)
    -- Defined in ‘GHC.Arr’
  ...plus 26 others
In the expression: mymerge [] []
In an equation for ‘t72’: t72 = mymerge [] []

我怀疑它试图告诉我没有足够的信息来推断 [] 的类型。如果我明确定义函数的类型,它会起作用:

t72 :: Ord a => [a]
t72 = mymerge [] []

这是让它工作的惯用方式吗?

更新:我不会按照建议将其标记为重复,另一个问题的答案没有提到单态限制。

【问题讨论】:

  • 你用的是什么版本?
  • 听起来你理解这个问题。你通常会给参数一个具体的类型,比如merge ([] :: [Int]) []
  • @karafka,我有 GHC 7.10.3
  • @jberryman,我对 Haskell 了解的不够多,无法判断这是否与您提到的问题重复 :-)

标签: haskell


【解决方案1】:

这不是臭名昭著的monomorphism restriction吗?在 GHCi 8.0.1 中,这在没有注释的情况下按预期工作:

Prelude> :t mymerge [] []
mymerge [] [] :: Ord a => [a]

因为:

Prelude> :showi language
base language is: Haskell2010
with the following modifiers:
  -XNoDatatypeContexts
  -XExtendedDefaultRules
  -XNoMonomorphismRestriction
  -XNondecreasingIndentation

所以这也有效:

{-# LANGUAGE NoMonomorphismRestriction #-}

mymerge :: Ord a => [a] -> [a] -> [a]
mymerge xs [] = xs
mymerge [] ys = ys
mymerge (x:xs) (y:ys) | x < y     = x : mymerge xs (y:ys)
                      | otherwise = y : mymerge (x:xs) ys

t72 = mymerge [] []

简而言之,默认情况下,t72 的类型将被推断为不像您预期​​的那样多态。

【讨论】:

  • 对,好点。所以t72 = mymerge [] [] 在编译时抛出该错误是由于单态限制,但是如果您想使用t72,则需要在某个时候解决歧义,例如通过打印它,执行== [] 等。在ghci 中我们可以说t72 == [],但这是由于扩展的默认规则
  • 是的,我同意,启用NoMonomorphismRestriction 或不使用来自原始问题t72 :: Ord a =&gt; [a] 的类型注释,它仍然是多态的,因此上述中的一个可能足以解决所有问题代码的所有部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多