【问题标题】:haskell foldr and variablehaskell 文件夹和变量
【发布时间】:2013-06-27 04:16:09
【问题描述】:

如何创建一个与此类似的函数,但 n 是一个变量,其数字以 1 开头并以 xs 的长度值结尾?

例如我希望[1,2,3] 返回3*1 + 2*2 + 1*3 的结果。

function :: [Int] -> Int
function xs = foldr (\x acc -> (x*n) + acc) 0 xs

【问题讨论】:

    标签: function haskell functional-programming fold


    【解决方案1】:

    一个惯用的 Haskell 答案可以是:

    function = sum . zipWith (*) [1 ..] . reverse
    

    从右到左阅读:你反转列表 (reverse),这样做你不需要倒数(从 n 到 1)而是向前数(1 到 n)......然后你用使用 * (zipWith (*) [1..]) 的索引,最后总结一下 (sum)。

    【讨论】:

    • Rance 是否可能想要一个不太通用的解决方案,例如:“function n = sum . zipWith (*) [1 .. ] . reverse $ take n [1 ..]”?
    • 根据他给function的签名,我不这么认为。
    • 顺便说一句,写[1 .. n] 比写take n [1 ..] 更容易;)
    【解决方案2】:

    使用zipWith

    import Data.List
    
    function :: [Int] -> Int
    function xs = sum $ zipWith (*) xs lst
                  where
                    lst = unfoldr (\x -> Just (x-1,x-1)) $ (length xs) + 1
    
    main = putStr $ show $ function [40,50,60]
    

    【讨论】:

    • 如果我理解正确的问题,function [40,50,60] 应该是 3*40 + 2*50 + 1*60,而不是 60*40+50*50+40*60
    【解决方案3】:
    function xs = fst $ foldr (\x (acc,n) -> (x*n+acc,n+1)) (0,1) xs
    

    或者也许更具可读性:

    function = fst . foldr f (0,1) where f x (acc,n) = (x*n+acc, n+1)
    

    【讨论】:

      猜你喜欢
      • 2021-03-18
      • 2023-01-20
      • 1970-01-01
      • 2015-02-08
      • 2023-03-13
      • 2017-03-15
      • 2022-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多