【问题标题】:How to get backtracking and IO using ListT?如何使用 List 进行回溯和 IO?
【发布时间】:2011-06-18 17:28:36
【问题描述】:

我真的不知道应该如何使用 List 转换器 ListT。比如这个简单的任务应该怎么做:

backtrack :: ListT IO ()
backtrack = do
    x <- lift getLine
    a <- x
    lift $ print a

函数的类型应该是什么?

这不是我想要完成的任务(我知道如何使用许多其他方法来解决这个问题),我只是想知道如何使用ListT 来完成这些任务。

【问题讨论】:

  • 您要完成什么任务?你实际上并没有说。
  • 我只是想了解如何使用ListT来获取带有IO的List Monad的特性。我所说的“这不是我想要完成的任务”的真正意思是我不想要不使用ListT 的问题的解决方案,因为我已经知道如何使用mapM 来完成此任务例子。
  • a &lt;- x 没有多大意义,因为x 属于“monad 类型”,例如m a 中的普通a。您可能想要x &lt;- liftGetline; lift $ print a
  • 标准库中的 ListT 实际上并不进行回溯。 ListT m 通常也不是单子,而 m 是。 ListT 有一个很好的实现,但我现在似乎找不到它:-(
  • @monadic 感谢您的贡献,但我并没有真正理解您的问题。 @luqui 你在说 LogicT 吗?!

标签: haskell io generic-list backtracking monad-transformers


【解决方案1】:

您应该查看ListT done right 和回溯LogicT 包。特别是 logict 中的 interleave 可以更好地处理无穷大。

【讨论】:

    【解决方案2】:

    这是你想要做的吗?

    import Control.Monad.List
    
    backtrack :: ListT IO ()
    backtrack = do
        x <- ListT getLine
        lift $ print x
    

    在 GHCi 中运行的示例:

    *Main> runListT backtrack
    foo
    'f'
    'o'
    'o'
    [(), (), ()]
    

    【讨论】:

    • 是的,这与我想要的相似。但是为什么你在 x &lt;- ListT getLine 中使用 ListT 构造函数不应该将 lift 用于内部 monad 中的操作?
    • 你也可以写成do x &lt;- lift getLine; a &lt;- ListT (return x); lift $ print a。也许这更容易理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 2021-03-10
    • 2020-02-25
    • 1970-01-01
    • 2021-12-11
    相关资源
    最近更新 更多