【发布时间】:2021-01-07 20:37:25
【问题描述】:
我已经开始学习 Haskell,并且我读到 Haskell 中的每个函数都只需要一个参数,我无法理解 Haskell 背后发生了什么神奇的事情使之成为可能,我想知道它是否有效。
示例
>:t (+)
(+) :: Num a => a -> a -> a
上面的签名意味着(+)函数接受一个Num然后返回另一个函数接受一个Num并返回一个Num
示例 1 相对简单,但我开始想知道当函数稍微复杂一点时会发生什么。
我的问题
为了这个示例,我编写了一个zipWith 函数并以两种方式执行它,一次传递一个参数,一次传递所有参数。
zipwithCustom f (x:xs) (y:ys) = f x y : zipwithCustom f xs ys
zipwithCustom _ _ _ = []
zipWithAdd = zipwithCustom (+)
zipWithAddTo123 = zipWithAdd [1,2,3]
test1 = zipWithAddTo123 [1,1,1]
test2 = zipwithCustom (+) [1,2,3] [1,1,1]
>test1
[2,3,4]
>test2
[2,3,4]
- 一次传递一个参数(scenario_1) 是否与一次传递所有参数一样有效(scenario_2)?
- 这些场景在 Haskell 实际计算
test1和test2方面是否有任何不同(除了场景_1 可能需要更多内存,因为它需要保存zipWithAdd和zipWithAdd123)李> - 这是正确的吗?为什么?在scenario_1中,我遍历
[1,2,3],然后遍历[1,1,1] - 这是正确的吗?为什么?在 scenario_1 和 scenario_2 我同时遍历两个列表
我意识到我在一篇文章中提出了很多问题,但我相信这些问题是相互关联的,并且会帮助我(以及其他刚接触 Haskell 的人)更好地了解 Haskell 中实际发生的事情,从而使这两种情况都成为可能.
【问题讨论】:
-
在这两种情况下,您同时遍历两个列表。
-
在
test2中你也每次都用一个参数调用它,因为zipWithCustom (+) [1,2,3] [1,1,1]是((zipWithCustom (+)) [1,2,3]) [1,1,1]的缩写。 -
@hdw3:它不运行该功能。 haskell 是 懒惰的。它只会在必要时执行某些操作,因此当您枚举列表时,您已经传递了
f和列表。 -
@hdw3:但更重要的是,这个想法是,如果您调用
zipWithCustom (+),您只需构造一个将获取列表的 new 函数,然后再构造一个将获取另一个列表。所以zipWith (+)基本上是构造一个new函数,而不是一个列表。
标签: performance function haskell arguments