【问题标题】:The real sense of list generators in haskell真正意义上的haskell列表生成器
【发布时间】:2016-02-11 18:40:32
【问题描述】:

据我了解,代码

l = [(a,b)|a<-[1,2],b<-[3,4]]

等价于

l = do
  a <- [1,2]
  b <- [3,4]
  return (a,b)

[1,2] >>= (\a -> [3,4] >>= (\b -> return (a,b)))

这种表达式的类型是 [(t,t1)] 其中 t 和 t1 在 Num 中。

如果我写类似

getLine >>= (\a -> getLine >>= (\b -> return (a,b)))

解释器读取两行并返回一个包含它们的元组。

但是我可以在列表生成器中使用 getLine 或类似的东西吗?

表达式

[x|x<-getLine]

返回错误“无法匹配预期类型[t0]' with actual typeIO String'”

但是,当然,这适用于 do-notation 或使用 (>>=)。

列表生成器有什么意义,它们与 do-notation 之间的实际区别是什么?

使用 list gens 时有任何类型限制吗?

【问题讨论】:

    标签: haskell


    【解决方案1】:

    这是一个明智的观察,你不是第一个偶然发现它的人。你是对的,[x|x&lt;-getLine] 的翻译会导致一个完全有效的单子表达式。关键是,我认为列表推导式 first 只是作为列表的便捷语法引入的,并且(可能)没有人认为人们可能会将它们用于其他 monad。

    但是,由于[] 的限制并不是真正必要的,所以有一个名为-XMonadComprehensions 的 GHC 扩展,它消除了限制并允许您准确地编写您想要的内容:

    Prelude> :set -XMonadComprehensions 
    Prelude> [x|x<-getLine]
    sdf
    "sdf"
    

    【讨论】:

    • 我听说过理解曾经适用于任何 monad,但是错误消息难以理解,所以它被改变了。不过我没有引用...
    • 好吧,如果在过去,翻译纯粹是重写并且独立于类型检查......也许在有人严格应用报告中的内容之前,这是有道理的。
    • @MathematicalOrchid:有this ticketthis wiki page;两者都表明 MonadComprehensions 最初是允许的,然后被删除,后来通过语言扩展添加回来。
    • @Zeta ...所以它在 Haskell 1.4 中。我希望我没有想象到...... :)
    【解决方案2】:

    我的理解是列表推导式只能用于构造列表

    然而,有一个叫做“monad comprehensions”的语言扩展允许你使用任意的monad。

    https://ghc.haskell.org/trac/ghc/wiki/MonadComprehensions

    【讨论】:

      猜你喜欢
      • 2013-08-12
      • 2016-06-14
      • 1970-01-01
      • 2014-06-24
      • 2011-06-28
      • 1970-01-01
      • 2017-12-13
      • 2017-06-26
      • 2023-03-24
      相关资源
      最近更新 更多