对看似等效的函数定义

时间:2017-11-09 21:18:19

标签: haskell selection-sort

我编写了2个Haskell函数:

unfold nhs xs | val == Nothing = []
              | otherwise      = b:unfold nhs a
   where val = nhs xs
         Just (b, a) = val

extractMin [] = Nothing
extractMin (x:xs) | val == Nothing || b > x = Just (x, xs)
                  | otherwise = Just (b, x:a)
   where val = extractMin xs
         Just (b, a) = val

第一个基本上从Data.List展开,第二个接受一个列表并返回一个Maybe元组,该元组由最小元素和列表的其余部分组成。这两个功能似乎都正常工作。

将extractMin应用于展开应该产生选择排序。但是,在这里我注意到了一些奇怪的行为。如果我将选择排序定义为:

ssort = unfold extractMin

编译器抛出错误:

test.hs:13:10:
    No instance for (Eq t0) arising from a use of ‘unfold’
    The type variable ‘t0’ is ambiguous
    Relevant bindings include
      ssort' :: [t0] -> [t0] (bound at test.hs:13:1)
    Note: there are several potential instances:
      instance (Eq a, Eq b) => Eq (Either a b)
        -- Defined in ‘Data.Either’
      instance forall (k :: BOX) (s :: k). Eq (Data.Proxy.Proxy s)
        -- Defined in ‘Data.Proxy’
      instance (GHC.Arr.Ix i, Eq e) => Eq (GHC.Arr.Array i e)
        -- Defined in ‘GHC.Arr’
      ...plus 28 others
    In the expression: unfold extractMin
    In an equation for ‘ssort'’: ssort' = unfold extractMin

test.hs:13:17:
    No instance for (Ord t0) arising from a use of ‘extractMin’
    The type variable ‘t0’ is ambiguous
    Relevant bindings include
      ssort' :: [t0] -> [t0] (bound at test.hs:13: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 27 others
    In the first argument of ‘unfold’, namely ‘extractMin’
    In the expression: unfold extractMin
    In an equation for ‘ssort'’: ssort' = unfold extractMin
Failed, modules loaded: none.

然而,

ssort xs = unfold extractMin xs

工作得很好。

我真的很困惑,因为我认为2个定义是等价的。任何帮助都表示赞赏,但基本上我想了解两个定义之间的区别是什么,以及为什么首先抛出错误。

0 个答案:

没有答案