第一个根据我的理解,digits 1234的评价应该是[1,2,3,4]。但我似乎遗漏了一些东西。有人能解释一下吗?
digits 1234
[1,2,3,4]
tyg4sfes1#
问题是digits在每次递归调用中都会反转字符串,而不是在外层只反转一次。尝试digits x = reverse (digits' x)(或者等价地,digits = reverse . digits'),看看是否可以解释其中的区别。
digits
digits x = reverse (digits' x)
digits = reverse . digits'
htrmnn0y2#
尽管amalloy给出了很好的答案,但这里有一种方法,可以在不涉及reverse库函数的情况下,按预期的顺序获得数字。我们使用了一个常见的技巧,即在递归调用的某个额外参数(“accumulator”)中累加结果,这里记为dgs。我们还使用了divMod库函数,它返回一个包含商和余数的对。
reverse
dgs
divMod
digits :: Int -> [Int] digits n = go [] n where base = 10 go dgs k = if (k < base) then (k:dgs) else let (q,r) = divMod k base in go (r:dgs) q
累加器通过连续的 prepending 操作来增长,以这种方式,数字以适当的顺序结束。
2条答案
按热度按时间tyg4sfes1#
问题是
digits
在每次递归调用中都会反转字符串,而不是在外层只反转一次。尝试digits x = reverse (digits' x)
(或者等价地,digits = reverse . digits'
),看看是否可以解释其中的区别。htrmnn0y2#
尽管amalloy给出了很好的答案,但这里有一种方法,可以在不涉及
reverse
库函数的情况下,按预期的顺序获得数字。我们使用了一个常见的技巧,即在递归调用的某个额外参数(“accumulator”)中累加结果,这里记为
dgs
。我们还使用了
divMod
库函数,它返回一个包含商和余数的对。累加器通过连续的 prepending 操作来增长,以这种方式,数字以适当的顺序结束。