2

我有一个[(String, [String], IO Int)]列表,我想对其进行排序。sortBy (\x -> ...) list要求我使用 IO 来获取 的内部值IO Int,这意味着我不能返回Ordering而只能IO Ordering返回sortBy函数。有没有办法对列表进行排序?

4

1 回答 1

7

每个元组的第三个元素是IO Int,因此它的值取决于外部世界。所以排序列表的顺序取决于外部世界。所以不,没有办法制作一个 [(String, [String], IO Int)]IO Int.

可以做的是创建一个值IO [(String, [String], Int)],然后将该函数提升到sortBymonadIO,为您提供另一个IO [(String, [String], Int)]将产生一个按 . 排序的列表Int。这不是一个纯列表,但您可以将 lift 任何其他纯函数注入IOmonad 以对其进行任意纯计算。

这样的事情会做:

import Control.Applicative
import Data.List

l :: [(String, [String], IO Int)]
l = [("Foo", [], return 2), ("Bar", [], return 1)]

f :: Monad m => (a, b, m c) -> m (a, b, c)
f (x, y, ioz) = ioz >>= \z -> return (x, y, z)

sl = sortBy (\(x, y, z) (x', y', z') -> compare z z') <$> mapM f l

我应该提一下,因为它可能不明显,这将IO Int按照它们最初出现在列表中的顺序运行这些操作。但是要对它们进行排序,您必须运行它们以获取Int值,并且它们必须以某种顺序运行。

于 2013-04-25T01:00:54.373 回答