我正在阅读“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 [] []
这是让它运作的惯用方法吗?
更新:我不会按照建议将其标记为副本,其他问题的答案未提及单态限制。
答案 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
的类型将被推断为比您期望的更少多态。