使用'mymerge'时没有(Ord a0)的实例

时间:2016-12-18 03:58:37

标签: haskell

我正在阅读“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 [] []

这是让它运作的惯用方法吗?

更新:我不会按照建议将其标记为副本,其他问题的答案未提及单态限制。

1 个答案:

答案 0 :(得分:2)

这不是臭名昭着的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的类型将被推断为比您期望的更少多态。