Haskell - 具有不纯函数的排序列表

KAc*_*ion 10 sorting io haskell

如何使用IO比较功能对列表进行排序?

sortWith :: [String] -> (String -> String -> IO Ordering) -> IO [String]
Run Code Online (Sandbox Code Playgroud)

Sortby期待(a->a->Ordering),我不知道,如何处理它.我懒得自己快速排序.

sdc*_*vvc 15

我担心没有简单的方法.如果有可能举起

sortBy :: Ord a => (a -> a -> Ordering) -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

sortByM :: (Ord a, Monad m) => (a -> a -> m Ordering) -> [a] -> m [a]
Run Code Online (Sandbox Code Playgroud)

您可以看到执行中的比较顺序sortBy,违反参照透明度.

一般来说,这很容易xxxM,xxx但不是相反.

可能的选择:

  • 实现monadic排序方法
  • 使用单子库,其中包含插入排序(如dflemstr的答案)
  • 使用unsafePerformIO一劈
  • 切换到按键排序并使用Schwartzian变换

    sortOnM :: (Monad m, Ord k) => (a -> m k) -> [a] -> m [a]
    sortOnM f xs = liftM (map fst . sortBy (comparing snd)) $
                     mapM (\x -> liftM (x,) (f x)) xs
    
    Run Code Online (Sandbox Code Playgroud)

  • `sortByM`没有违反它.将`sortBy`提升为`sortByM`的潜在功能.两个排序函数`sortBy1,sortBy2 :: Ord a =>(a - > a - > Ordering) - > [a] - > [a]`应该是完全可互换的,即使它们以不同的顺序执行比较.如果你让'fij = print(i,j)>>返回(比较ij)`那么`lift sortBy1 f`可能会打印出与提升sortBy2 f`不同的序列. (3认同)
  • 你能详细说明为什么`sortByM`违反了引用透明度吗? (2认同)