gpt4 book ai didi

haskell - 为什么即使在下面的示例中,n-reduction 也不适用于过滤器?

转载 作者:行者123 更新时间:2023-12-02 20:41:27 25 4
gpt4 key购买 nike

我正在关注'Learn Haskell Fast and Hard'我能够理解其中的大部分内容,但我对以下代码示例有两个问题。

  1. 在第一个函数中,为什么我不需要 l 但在第二个版本中我确实需要 l
  2. evenSum1 中,当递归调用该函数时,filter 会在列表上一次又一次调用,或者 filter 仅被调用一次第一次通话时?

.

evenSum = accumSum 0 
where
accumSum n [] = n
accumSum n (x:xs) =
if even x
then accumSum (n+x) xs
else accumSum n xs

evenSum1 l = mysum 0 (filter even l)
where
mysum n [] = n
mysum n (x:xs) = mysum (n+x) xs

最佳答案

您实际上可以删除 l在第二个示例中也是如此,但您需要切换到所谓的 point free notation并使用函数组合运算符 (.) :

evenSum1 = mysum 0 . filter even
where
mysum n [] = n
mysum n (x:xs) = mysum (n + x) xs

evenSum1filter even函数只会被调用一次。发生的情况是filter even运行完传入的列表,然后将其输出传递给 mysum 0

<小时/>

无点表示法快速入门

假设你有一个函数 add :

add :: Int -> Int -> Int
add x y = x + y

然后你想要创建一个函数 add5 Int 总是加 5 。你可以这样做

add5 :: Int -> Int
add5 y = add 5 y

但是由于函数是 Haskell 中的第一类对象,我们可以部分应用函数,这相当于说

add5 :: Int -> Int
add5 = add 5

另一种看待它的方法是向 add 的类型签名添加一些可选的括号。 :

add :: Int -> (Int -> Int)
add x y = x + y

这样写,我们可以说add是一个接受单个 Int 的函数参数并返回一个新函数 Int -> Int 。所以如果我们给出 add单个Int ,我们得到一个新函数。这也让我们可以编写这样的表达式

filter even list

而不是

filter (\x -> even x) list

无点表示法的一个很好的经验法则是变量可以从最后一个 $ 的末尾删除。进入. :

f x y = h x $ g y
f x = h x . g

f x y z = h x $ g y $ j z
f x y = h x $ g y . j

这并不总是适用于多参数函数:

f x y = h $ g x y

不一样

f = h . g

因为h . g不会输入检查。这是因为隐式括号:

f x y = h $ (g x) y
f x = h . (g x)

现在有括号妨碍删除 x论证。

另外,请记住 f x y = h (g x y)相当于 f x y = h $ g x y ,因此通常可以将最外面的括号变成 $相反,可能让您进行 eta 缩减并更改 $. 。如果这一切看起来令人困惑,您还可以获取 pointfree打包 hackage,其中包含一个命令行工具,可以自动为您执行 eta-reductions。

关于haskell - 为什么即使在下面的示例中,n-reduction 也不适用于过滤器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25816444/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com