我正努力通过在线the CIS 194 course at the 课程学习Haskell。在其中一个练习中,学生应该重写一个函数:
fun1 :: [Integer] -> Integer
fun1 [] = 1
fun1 (x:xs)
| even x = (x - 2) * fun1 xs
| otherwise = fun1 xs变成一个更“惯用”的哈斯克尔。我把函数重写为
fun1 :: [Integer] -> Integer
fun1 xs =
let spl = partition even xs
in foldl (*) 1 ((map (subtract 2) (fst spl)) ++ snd spl)这看起来..。利比。它将几乎每一个字符转换成我将如何用clojure编写它。在赋值中,它给出了使用takeWhile和iterate重写函数的提示。虽然我表面上理解这些函数的作用,但我并不清楚如何重写该函数来使用它们。如何使用takeWhile和iterate重写
发布于 2017-06-23 14:43:39
这实际上与takeWhile没有多大关系。您只需计算给定列表中的每个偶数x-2的乘积x。的确:
fun1 :: [Integer] -> Integer
fun1 [] = 1 -- the product of an empty list is 1
fun1 (x:xs)
-- if the number is even, we multiply (x-2) with the remaining part
| even x = (x - 2) * fun1 xs
-- if the number is odd, we ignore x and return the fun1 of the tail
| otherwise = fun1 xs所以我们可以把它写成:
fun1 :: Integral i => [i] -> i
fun1 = product . map (subtract 2) . filter even如果您不能使用product,您可以使用--就像在问题中那样--使用:
fun1 :: Integral i => [i] -> i
fun1 = foldl (*) 1 . map (subtract 2) . filter even这就是我们所称的无点版本:在fun1或任何lambda表达式的头上没有参数。因此,我们并不是从价值的角度来思考,而是从功能的角度来思考。
对于列表[1,3,4],这将生成:
Prelude> (foldl (*) 1 . map (subtract 2) . filter even) [1,3,4]
2https://stackoverflow.com/questions/44724119
复制相似问题