【问题标题】:Haskell: is "list comprehension" using eager evaluation?Haskell:“列表理解”是否使用热切评估?
【发布时间】:2023-03-08 20:25:01
【问题描述】:

我刚试过这个:

Prelude> [x*2|x<-[1..10]]
[2,4,6,8,10,12,14,16,18,20]

嗯,它似乎不像 F# 的“seq”,它是惰性求值的。这里这个集合中的所有元素都被打印出来了,所以看起来“列表理解”是急切的评估。

如果我想构建一个“惰性评估”的模型怎么办? 谢谢。

【问题讨论】:

    标签: list haskell list-comprehension lazy-evaluation


    【解决方案1】:

    在 Haskell 一切(几乎)都是懒惰的,这没什么区别

    但是如果你让 GHCi 打印它(你对输入做了),它会评估所有的内容

    要查看它,请使用:

    Prelude> let xs = [x*2|x<-[1..10]]
    Prelude> :sprint xs
    xs = _
    

    _ 表示此处未评估 thunk


    顺便说一句:这就是为什么 Haskell 对这样的事情没有任何问题:

    let xs = [x*2|x<-[1..]]
    

    这是一个无限列表 - 现在如果您要求它打印出来,它会 需要一些时间 ;)

    对于 F# 的 seq { ... } 也是如此,但对于 F# 的列表则不然!

    【讨论】:

    • 谢谢,但我不太明白 :sprint 的作用,关于“惰性评估”,因为:Prelude> let a=2 Prelude> :sprint a a = _ 似乎仍然打印“_”
    • :sprint 是一个GHCi Command,它“打印一个值而不强制其评估。:sprint 类似于 :print,不同之处在于未评估的子项不绑定到新变量,它们只是用'_'表示。” - 所以你可以检查什么得到评估/强制,什么没有
    • Here is a very good introduction 在这个东西上^^
    • @viksantata 那是因为2 不是 Haskell 中的评估值。它是一个多态表达式,其评估取决于其类型。试试2 :: Int。
    • @Carl 对...我完全误读了评论/问题 - 感谢您指出这一点
    【解决方案2】:

    你可以通过请求一个无限列表来自己测试:

    Prelude> take 10 [ x*2 | x <- [1..], x `mod` 3 == 0 ]
    [6,12,18,24,30,36,42,48,54,60]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-02
      • 2021-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多