考虑一下我用来解决欧拉问题 58 的代码:
diagNums = go skips 2
where go (s:skips) x = let x' = x+s
in x':go skips (x'+1)
squareDiagDeltas = go diagNums
where go xs = let (h,r) = splitAt 4 xs
in h:go r
我不喜欢第二个函数中的模式匹配。它看起来比必要的复杂!这对我来说经常出现。这里,splitAt
返回一个元组,所以我必须先解构它,然后才能递归。当我的递归本身返回一个我想要修改的元组时,同样的模式可能会更烦人。考虑:
f n = go [1..n]
where go [] = (0,0)
go (x:xs) = let (y,z) = go xs
in (y+x, z-x)
与漂亮而简单的递归相比:
f n = go [1..n]
where go [] = 0
go (x:xs) = x+go xs
当然,这里的函数纯粹是胡说八道,可以用完全不同的更好的方式编写。但我的观点是,每当我需要通过递归返回多个值时,就会出现模式匹配的需求。
有什么方法可以避免这种情况,也许是通过使用Applicative
或类似的方法?或者你会认为这种风格是惯用的吗?