代码之家  ›  专栏  ›  技术社区  ›  Witiko

如何根据IO Int值对列表进行排序

  •  2
  • Witiko  · 技术社区  · 13 年前

    我有一个 [(String, [String], IO Int)] 列表,我想对其进行排序。 sortBy (\x -> ...) list 要求我使用IO获取 IO Int ,这意味着我不能回来了 Ordering 但仅限于 IO Ordering sortBy 作用有什么方法可以对列表进行排序吗?

    1 回复  |  直到 13 年前
        1
  •  7
  •   Ben    13 年前

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

    你做了什么 可以 要做的就是让 IO [(String, [String], Int)] ,然后抬起 sortBy 作用 进入 这个 IO monad再给你一个 IO[(字符串,[String],Int)] 这将产生一个按 Int 。这不是一个纯列表,但您可以将lift任何其他纯函数注入 国际组织 monad对其进行任意纯计算。

    这样做可以:

    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内部 按照它们最初出现在列表中的顺序执行操作。但要对它们进行排序,你必须运行它们才能获得 国际 值,并且它们必须在中运行 一些 顺序