为了学习 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..]
为了学习 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..]
我认为您正在寻找用于强制对数据结构进行全面评估的哪个deepseq
。Control.DeepSeq
它的类型签名是deepseq :: NFData a => a -> b -> b
,并且它通过在返回第二个参数之前完全评估其第一个参数来工作。
table = t `deepseq` t
where t = M.fromList . zip ['a'..'z'] $ [1..]
请注意,这里仍然存在一些惰性。table
在您尝试使用它之前不会被评估,但此时将评估整个地图。
请注意,正如 luqui 所指出的,Data.Map
它的键已经很严格,所以只有当你希望它的值也很严格时,这样做才有意义。
一般的答案是,您编写的一些代码必须强制评估整个数据结构。例如,如果您有一个列表:
strictList xs = if all p xs then xs else []
where p x = x `seq` True
我确信已经有一些类型类可以递归地应用这种强制以及标准数据类型的实例。