list - Haskell 中列表的逐元素加法(乘法、求幂等)

标签 list haskell dictionary

如果我在 Haskell 中有两个相同大小的列表

list1 = [1.0,2.0,3.0]
list2 = [3.0,5.0,7.0]

我如何执行逐元素加法来创建第三个大小相等的列表?

[4.0,7.0,10.0]

具体来说,我想做一个这样的函数:

listAdd :: [Float] -> [Float] -> [Float]
listAdd a b
    | length a /= length b = error "length mismatch"
    otherwise              = ????

我不知道用什么来代替“????”。我认为它必须涉及“map”和某个版本的“+”,但部分评估的事情让我感到困惑,而且事实证明正确的语法难以捉摸。

编辑 1:

我以为我理解了与 cons 运算符的模式匹配,所以我接下来尝试了这个:

listAdd :: [Float] -> [Float] -> [Float]
listadd (x:xs) (y:ys) = (x+y) : listAdd xs ys
listAdd []     []     = []
listAdd _      _      = error "length mismatch"

但是还是有问题,因为

listAdd [1.0,2.0] [2.0,3.0]

直接越过有用的模式并返回错误。

编辑 2:

消除错别字后,

listAdd :: [Float] -> [Float] -> [Float]
listAdd (x:xs) (y:ys) = (x+y) : listAdd xs ys
listAdd []     []     = []
listAdd _      _      = error "length mismatch"

按照宣传的方式工作。由于管理任意维度张量的类型在我研究的早期超出了我的范围,我决定只将它扩展到矩阵加法:

mAdd :: [[Float]] -> [[Float]] -> [[Float]]
mAdd (x:xs) (y:ys) = listAdd x y : mAdd xs ys
mAdd []     []     = []
mAdd _      _      = error "length mismatch"

我意识到将功能绑定(bind)在一起可能并不理想,因为它降低了模块化/可移植性,但它完成了我需要它做的事情。

编辑 3:

我希望现在宣布某种程度的学习已经发生还为时过早。我现在有这个:

listCombine :: (Float -> Float -> Float) -> [Float] -> [Float] -> [Float]
listCombine f (x:xs) (y:ys) = (f x y) : listCombine f xs ys
listCombine f []     []     = []
listCombine _ _      _      = error "length mismatch"

这可能与 zipWith 相同,除了它会给出长度不匹配的错误。它处理了我抛给它的极端情况,并取得了预期的结果。

最佳答案

单独计算参数列表的长度是个坏主意。我们通常希望消耗尽可能少的输入,同时产生尽可能多的输出。这被称为“不强制输入太多”,即尽可能懒惰。

在您的情况下,当我们分析这两个参数时,如果一个列表为空而另一个不为空,我们将知道长度不匹配:

listAdd :: [Float] -> [Float] -> [Float]
listAdd (x:xs) (y:ys) =  (x+y) : listAdd ... ...
listAdd []     []     = []
listAdd _      _      =  error "length mismatch"

这样它甚至可以用于无限列表。

与此类似的内置函数是zipWith,但它忽略了列表长度不匹配:

Prelude> zipWith(+) [1,2] [3]
[4]

等同于上面定义最后两行替换为catch-all子句

listAdd _      _      = []

关于list - Haskell 中列表的逐元素加法(乘法、求幂等),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21804967/

相关文章:

python - 如何从 Python 中的像素值列表创建 PNG 图像文件?

python - 如何在Python中的正则表达式中使用字典?

Swift:仅从 NSUserDefaults 中删除第一个对象

不同数据类型的 Haskell 模式匹配

haskell - 为什么 Prelude 具有相同的功能,只是参数不同?

python - 将多个字典元素追加到列表中

python - 如何链接在两个列表之间创建连接?

Python:如何将剩余的列表元素添加到列表中,类似于解压?

list - SwiftUI 问题 : Decreasing the clickable area of buttons inside the scrollview if the view is adjacent to the list

Haskell - 想要来自不改变的文件的全局变量