【发布时间】:2019-08-05 20:17:28
【问题描述】:
我正在尝试构建一个与 Prelude 的 product 基本相同的 Haskell 函数。然而,与那个函数不同的是,它应该具有以下两个属性:
- 它应该在常量空间中运行(忽略一些像
Integer这样的数字类型不是这样的事实)。例如,我希望myProduct (replicate 100000000 1)最终返回 1,这与 Prelude 的product不同,后者会用完我所有的 RAM,然后给出*** Exception: stack overflow。 - 它遇到 0 时应该短路。例如,我希望
myProduct (0:undefined)返回 0,这与 Prelude 的product不同,它提供*** Exception: Prelude.undefined。
这是我到目前为止的想法:
myProduct :: (Eq n, Num n) => [n] -> n
myProduct = go 1
where go acc (x:xs) = if x == 0 then 0 else acc `seq` go (acc * x) xs
go acc [] = acc
这正是我希望它用于列表的方式,但我想将其概括为具有(Foldable t, Eq n, Num n) => t n -> n 类型。是否可以使用任何折叠来做到这一点?如果我只使用foldr,那么它会短路但不会是常数空间,如果我只是使用foldl',那么它将是常数空间但不会短路。
【问题讨论】:
-
顺便说一句:
product在编译的程序中不会堆栈溢出。
标签: haskell fold space-complexity short-circuiting