【问题标题】:Write Quick Sort in Haskell and need help to resolve the issue在 Haskell 中编写快速排序并需要帮助来解决问题
【发布时间】:2017-03-05 01:58:49
【问题描述】:

我尝试在 Haskell 中编写一个快速排序,我知道那里有很多版本。

这个对于 Int 类型来说非常简单

quickSort1::[Int]->[Int]
quickSort1 [] = []
quickSort1 (x:xs) = [l | l <- xs, l < x] ++ [x] ++ [ r | r <- xs, r > x]

我可以在 Main 上打印如下

print $ quickSort1 []   -- output []
print $ quickSort1 [2, 1] -- output [1, 2]

我将上面的 quickSort1 修改为使用 (Ord a) 而不是 Int 的“更通用”类型

quickSort2::(Ord a)=>[a]->Maybe [a]
quickSort2 [] = Nothing 
quickSort2 (x:xs)  = Just $ [ l | l <- xs, l < x] ++ [x] ++ [ r | r <- xs, r > x] 

在我的 Main 上,我可以运行

有效

print $ quickSort2 [2, 1] -- output [1, 2]

我在运行时遇到编译器错误

print $ quickSort2 [] -- got error 

谁能向我解释一下我的新版 quickSort2 发生了什么

【问题讨论】:

  • “谁能向我解释一下我的新版 quickSort2 发生了什么?”——没什么好担心的。如果您再次阅读错误(并且您应该将错误添加到此处的问题中,在这种情况下 - 它使每个人的事情变得更容易!),您可能会发现(我猜)它基本上是在说它没有不知道空列表应该具有哪种类型。如果我是对的,print $ quickSort2 ([] :: [Int]) 不会导致错误,并且当你在程序的其余部分中使用它时,你的函数会正常工作,只要你给东西类型签名。
  • 顺便问一下,您使用的是哪个版本的 GHC? (如果您不知道,请在终端中运行ghc --version。)
  • 附注 - 我希望您知道您的快速排序实现不正确quicksort1 [10,9..1] /= [1..10]quicksort1 [5,5,5] 也是如此。我正在使用 ghc 8.0.1 和 7.10.3,我无法重现任何错误!为您的第二个快速排序版本
  • Glorious Glasgow Haskell 编译系统,版本 7.10.3
  • 1) 您的 quickSort 没有任何递归调用。这肯定是错误的。 2)永远不要在不发布错误的情况下说“我遇到错误”!它可能对你没用,但对潜在的回答者来说很宝贵。 3)为什么可能?我希望排序总是返回一个列表...

标签: haskell


【解决方案1】:

我假设你使用了一个文件 foo.hs 并在其中

main = print $ quicksort []

quicksort = ... - as defined above in quickSort2

然后当您runghc foo.hs 时,您会收到两条错误消息

foo.hs:3:8: error:
    • Ambiguous type variable ‘a0’ arising from a use of ‘print’
      prevents the constraint ‘(Show a0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘a0’ should be.
      These potential instances exist:
        instance Show Ordering -- Defined in ‘GHC.Show’
        instance Show Integer -- Defined in ‘GHC.Show’
        instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
        ...plus 22 others
        ...plus 11 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the expression: print $ quicksort []
      In an equation for ‘main’: main = print $ quicksort []

有人告诉你 ghc 无法告诉你要使用什么 Show 实例,而 ghc 8 已经告诉你如何解决这个问题:

添加类型注释(正如@duplode 已经建议的那样)

main = print $ quicksort ([] :: [Int])

第二条错误信息非常相似但略有不同

foo.hs:3:16: error:
    • Ambiguous type variable ‘a0’ arising from a use of ‘quicksort’
      prevents the constraint ‘(Ord a0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘a0’ should be.
      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 five instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the second argument of ‘($)’, namely ‘quicksort []’
      In the expression: print $ quicksort []
      In an equation for ‘main’: main = print $ quicksort []

在第一条消息中,print 函数需要一个 Show 实例 - 这里你承诺 quicksort 提供可订购的列表 - 但没有说明使用哪个,所以 GHC 抱怨 Ord使用。

这两条消息都是因为[] 过于多态,它可能是任何东西的列表 - [Int] 很好,但它也可能类似于[Int -&gt; Bool],它既不是Showable 也不是@ 987654337@erable。

你也可以为quicksort 提供一些奇怪的东西,比如一个

newtype HiddenInt = HI Int deriving (Ord) --but not Show

这适用于quicksort 函数,但不适用于print

旁注

您的 quicksort 函数需要递归才能真正正确 - 正如我在 cmets 中指出的那样 - 您的算法存在逻辑问题 - 请务必正确测试您的函数,例如

import Data.List (sort)

main :: IO ()
main = do print $ "quicksort [10,9..1] == Just (sort [10,9..1]) is: "
           ++ show $ quicksort ([10,9..1]::Int]) == Just (sort ([10,9..1]::Int]))
          print $ "quicksort [5,5,5] == Just (sort [5,5,5]) is: "
           ++ show $ quicksort ([5,5,5] :: [Int]) == Just (sort ([5,5,5] :: [Int]))

quicksort :: (Ord a) => [a] -> Maybe [a]
quicksort = ...

或者,如果您有兴趣,请查看 QuickCheck - 它更高级一些,但是朝着正确方向迈出的一步,可以验证您的算法/功能是否按照您期望的方式工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    相关资源
    最近更新 更多