我正在寻找一种优雅的方式来编写以下代码:
然而,每次调用multipleProducts时,Haskell似乎都会计算gs和count,这需要很长时间,而不是仅在第一次计算,因为e的值始终与multipleProducts相同。有没有更好的避免重新计算的优雅方法?除了使用一个函数预先计算counts并将其存储在本地变量中,然后将其传递给onlyOneEl而不使用where之外?
因为我稍后要基于不同的集合重复使用onlyOneEl,并且我想避免拥有多个counts变量。
我理解这里为什么它不会每个函数计算一次,但是,我没有使用x作为我的最后一个参数,因此无法完全以这种方式执行。
提前感谢!
import Data.List
import Data.Maybe
combi = [(x,y) | x <- [2..100], y <- [x..100]]
gsp = group (sort [x*y | (x,y) <- combi])
counts = zip (map head gsp) (map length gsp)
multipleProducts x = (fromJust (lookup x counts)) > 1
possibleComb1 = [(x,y) | (x,y) <- combi, multipleProducts (x*y)]
由于我多次重复使用相同的模式,但基于不同的输入集合而不是 [x*y | (x,y) <- combi]
,因此我编写了以下代码。
import Data.List
import Data.Maybe
combi = [(x,y) | x <- [2..100], y <- [x..100]]
onlyOneEl e x = (fromJust (lookup x counts)) == 1
where gs = group (sort e)
counts = zip (map head gs) (map length gs)
multipleProducts = not.(onlyOneEl [x*y | (x,y) <- combi])
possibleComb1 = [(x,y) | (x,y) <- combi, multipleProducts (x*y)]
然而,每次调用multipleProducts时,Haskell似乎都会计算gs和count,这需要很长时间,而不是仅在第一次计算,因为e的值始终与multipleProducts相同。有没有更好的避免重新计算的优雅方法?除了使用一个函数预先计算counts并将其存储在本地变量中,然后将其传递给onlyOneEl而不使用where之外?
因为我稍后要基于不同的集合重复使用onlyOneEl,并且我想避免拥有多个counts变量。
我理解这里为什么它不会每个函数计算一次,但是,我没有使用x作为我的最后一个参数,因此无法完全以这种方式执行。
提前感谢!
onlyOneEl e = \ x -> ... where ...
,看看这是否有所帮助。 - Louis WassermanData.List.group
函数有点令人讨厌。我建议使用 Data.List.NonEmpty.group 代替,因为它可以避免你使用部分函数 (Prelude.head
) 来检查结果。相比之下,Data.List.NonEmpty.head
是完全安全的。 - dfeuerfromJust
。 - dfeueronlyOneEl
的主体移动到multipleProducts
中。 - jberryman