【问题标题】:Product of Elements in a list by using head, tail and null使用 head、tail 和 null 对列表中的元素进行乘积
【发布时间】:2016-08-11 09:35:59
【问题描述】:

所以基本上我应该使用 head 来获取第一个元素,然后乘以并迭代带有 tail 和 null 的列表。我对haskell很陌生,所以我根本不了解流量控制。下面的代码已经可以工作了,我只需要弄清楚在哪里使用 tail 并遍历列表。

module Blueprint where
import Prelude


x=1
prod :: [Integer] -> Integer
prod n 
|null n == True = 0
|null n== False = x*head n 

添加一些伪代码:

x=1
prod :: [Integer] -> Integer
prod n 
|null n == True = 0
|null n== False = x*head n  do tail n repeat until null n == true   

任何帮助都会很棒。谢谢。

【问题讨论】:

  • 教导使用部分函数来执行这样的任务,当模式匹配会更安全和更简单时,应该被视为刑事犯罪。 ;-P
  • 是的,我的教授不这么认为:D
  • 我实际上可以理解教授进行这些练习:他们希望确保您理解head,tail等。尽管如此,如果我必须教 Haskell,我不会提及它们(如果不是在最后),以确保模式匹配得到很好的理解。我也会推迟守卫:最近在 SO 守卫看到了很多虐待。甚至应该避免在警卫null n == True==False 之上。 (x == True 等价于x,我会在最后一种情况下使用otherwise——当然,如果使用模式匹配,周围就没有警卫了……)

标签: haskell


【解决方案1】:

你几乎成功了!您只需要递归调用prod 得到列表尾部的乘积,然后将结果乘以列表头部。

prod :: [Int] -> Int
prod xs
    | null xs = 1
    | otherwise = head xs * prod (tail xs)  -- note recursive call to prod

顺便说一句,使用 模式匹配 来解构您的列表比手动调用 headtailnull 更为惯用。

prod [] = 1
prod (x:xs) = x * prod xs

希望你能看到这与上面的代码是等价的。

Terser 仍然将prod 表达为折叠

prod = foldr (*) 1

foldr 是标准的 Haskell 习惯用法,用于一次使用一个列表元素。它是这样定义的:

foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f acc [] = acc
foldr f acc (x:xs) = f x acc (foldr f acc xs)

在该定义中用* 替换f1 替换acc,您将从上面恢复prod

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    相关资源
    最近更新 更多