【问题标题】:How to make a table (Data.Map) strict in haskell?如何在haskell中使表(Data.Map)严格?
【发布时间】:2011-08-25 10:58:51
【问题描述】:

为了学习 Haskell(好语言),我正在尝试来自 Spoj 的问题。

我有一个包含 19000 个元素的表,这些元素在编译时都是已知的。 如何使用“seq”使表格严格? 这是我的代码中的一个(强)简化示例。

import qualified Data.Map as M

-- table = M.fromList . zip "a..z" $ [1..]  --Upps, incorrect. sorry
table = M.fromList . zip ['a'..'z'] $ [1..]

【问题讨论】:

  • 你知道吗?为什么你需要严格?如果不是,我会说 YAGNI。
  • 据我所知,这只是 4 个元素?
  • 你到底要严格什么?存储在地图中的元素?地图本身的构造?为什么?
  • 严格是指您希望在编译时评估(创建)表吗?
  • @Jogusa 我认为说服 ghc 在编译时构建表将非常困难。如果你绝对必须,那么 Template Haskell 可以做到,但不能使用 Data.Map。但是为什么在第一次访问时有一点额外的时间不好呢?

标签: performance haskell data-structures compile-time strictness


【解决方案1】:

一般的答案是,您编写的一些代码必须强制评估整个数据结构。例如,如果您有一个列表:

 strictList xs = if all p xs then xs else []
      where p x = x `seq` True

我确信已经有一些类型类可以递归地应用这种强制以及标准数据类型的实例。

【讨论】:

    【解决方案2】:

    我认为您正在寻找 Control.DeepSeq 中的 deepseq,它用于强制对数据结构进行全面评估。

    它的类型签名是deepseq :: NFData a => a -> b -> b,它的工作原理是在返回第二个参数之前完全评估它的第一个参数。

    table = t `deepseq` t
      where t = M.fromList . zip ['a'..'z'] $ [1..]
    

    请注意,这里仍然存在一些惰性。 table 在您尝试使用它之前不会被评估,但此时将评估整个地图。

    请注意,正如 luqui 所指出的,Data.Map 的键已经很严格,因此只有在您希望它的值也严格时才有意义。

    【讨论】:

    • Data.Map 的键是严格的,所以这没有任何作用。
    • @luqui:是的,但它的值并不严格。这是。
    • 在这种情况下什么都不做。嗯……也许不是。如果值列表是有限的,即使[1..10^10^100] 也是无效的(因为我们必须与正确的端点进行比较以查看列表是否应该结束,从而强制每个值)。但由于它是无限的,因此强制可能最终实际上会进行一些计算。呼……微妙的东西。
    • @luqui:我假设 OP 在他的值中存储了一些更有趣的东西。否则,就没有理由这样做了。
    • 是的,这是有道理的。我的元认知失败了。
    猜你喜欢
    • 1970-01-01
    • 2014-01-01
    • 2016-09-11
    • 2014-12-14
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 1970-01-01
    • 2011-07-30
    相关资源
    最近更新 更多