您几乎可以使用您建议的语法编写它,因此:
lcms (a:b:c) = lcms (lcm a b:c)
lcms list = list
我发现第二个子句有点奇怪,但并不可怕:它优雅地处理空列表,尽管当你知道你最多会返回一个项目时返回一个列表可能会被一些 hasochists 认为对你的类型有点不精确。您还可以考虑使用Maybe
规范的 0 或 1 元素类型:
lcms (a:b:c) = lcms (lcm a b:c)
lcms [answer] = Just answer
lcms [] = Nothing
另一个不错的选择是确定一个合理的基本案例。对于二元运算,运算的单位通常是一个不错的选择,所以对于lcm
,我会选择1
,因此:
lcms (a:b:c) = lcms (lcm a b:c)
lcms [answer] = answer
lcms [] = 1
通常,尽可能避免显式递归。另一个答案显示了如何迈出这一步。在这种情况下,有一个中间转换使基本情况在美学上更令人愉悦:而不是将您的累加器保持在列表的头部——这只是偶然地起作用,因为你的累加器与列表元素的类型相同——一个可以使累积更明确或更少。因此,其中之一:
lcms (x:xs) = lcm x (lcm xs)
lcms [] = 1
-- OR
lcms = go 1 where
go acc (x:xs) = go (lcm acc x) xs
go acc [] = acc
这两种实现对应于选择foldr
或foldl
消除显式递归;foldl'
将类似于第二个,但有一个额外的seq
:
lcms = go 1 where
go acc (x:xs) = let acc' = lcm acc x in acc' `seq` go acc' xs
go acc [] = acc