首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用外卖和迭代的惯用haskell

使用外卖和迭代的惯用haskell
EN

Stack Overflow用户
提问于 2017-06-23 14:39:05
回答 1查看 381关注 0票数 1

我正努力通过在线the CIS 194 course at the 课程学习Haskell。在其中一个练习中,学生应该重写一个函数:

代码语言:javascript
复制
fun1 :: [Integer] -> Integer
fun1 [] = 1
fun1 (x:xs)
  | even x = (x - 2) * fun1 xs
  | otherwise = fun1 xs

变成一个更“惯用”的哈斯克尔。我把函数重写为

代码语言:javascript
复制
fun1 :: [Integer] -> Integer
fun1 xs =
  let spl = partition even xs
  in foldl (*) 1 ((map (subtract 2) (fst spl)) ++ snd spl)

这看起来..。利比。它将几乎每一个字符转换成我将如何用clojure编写它。在赋值中,它给出了使用takeWhileiterate重写函数的提示。虽然我表面上理解这些函数的作用,但我并不清楚如何重写该函数来使用它们。如何使用takeWhileiterate重写

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-23 14:43:39

这实际上与takeWhile没有多大关系。您只需计算给定列表中的每个偶数x-2的乘积x。的确:

代码语言:javascript
复制
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

所以我们可以把它写成:

代码语言:javascript
复制
fun1 :: Integral i => [i] -> i
fun1 = product . map (subtract 2) . filter even

如果您不能使用product,您可以使用--就像在问题中那样--使用:

代码语言:javascript
复制
fun1 :: Integral i => [i] -> i
fun1 = foldl (*) 1 . map (subtract 2) . filter even

这就是我们所称的无点版本:在fun1或任何lambda表达式的头上没有参数。因此,我们并不是从价值的角度来思考,而是从功能的角度来思考。

对于列表[1,3,4],这将生成:

代码语言:javascript
复制
Prelude> (foldl (*) 1 . map (subtract 2) . filter even) [1,3,4]
2
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44724119

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档