gpt4 book ai didi

haskell - Haskell中函数组合的困惑

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

考虑以下 ghci 中的函数定义。

let myF = sin . cos . sum 

在哪里, 。代表两个函数的组合(右结合)。这个我可以打电话
myF [3.14, 3.14]

它给了我想要的结果。显然,它将列表 [3.14, 3.14] 传递给函数“sum”,并将其“结果”传递给 cos 等等。但是,如果我在口译员中这样做
let myF y = sin . cos . sum y 

或者
let myF y = sin . cos (sum y) 

然后我遇到了麻烦。将其修改为以下内容给了我想要的结果。
let myF y = sin . cos $ sum y 

或者
let myF y = sin . cos . sum $ y 

(.) 的类型表明以下形式不应该有问题,因为“sum y”也是一个函数(不是吗?毕竟在 Haskell 中一切都是函数?)
let myF y = sin . cos . sum y -- this should work?

更有趣的是,我可以使用两个(或多个)参数(考虑将列表 [3.14, 3.14] 作为两个参数 x 和 y 传递),我必须编写以下内容
let (myF x) y = (sin . cos . (+ x)) y 
myF 3.14 3.14 -- it works!
let myF = sin . cos . (+)
myF 3.14 3.14 -- -- Doesn't work!

HaskellWiki 上有一些关于这种形式的讨论,他们称之为“PointFree”形式 http://www.haskell.org/haskellwiki/Pointfree .通过阅读这篇文章,我怀疑这种形式与两个 lambda 表达式的组合不同。当我尝试画一条分隔这两种样式的线时,我感到很困惑。

最佳答案

让我们看看 types 。对于 sincos 我们有:

cos, sin :: Floating a => a -> a

对于 sum :
sum :: Num a => [a] -> a

现在, sum y 把它变成了
sum y :: Num a => a

这是一个值,而不是函数(您可以将其命名为不带参数的函数,但这非常棘手,您还需要命名 () -> a 函数 - 某处对此进行了讨论,但我现在找不到链接 - Conal 谈到它)。

无论如何,尝试 cos . sum y 是行不通的,因为 . 期望双方都有类型 a -> bb -> c (签名是 (b -> c) -> (a -> b) -> (a -> c) )并且 sum y 不能用这种风格编写。这就是为什么您需要包含括号或 $ 的原因。

至于无点风格,简单的翻译方法是这样的:
  • 带你函数并将函数的最后一个参数移动到由函数应用程序分隔的表达式的末尾。例如,在 mysum x y = x + y 的情况下,我们最后有 y,但我们现在无法删除它。相反,重写为 mysum x y = (x +) y 它可以工作。
  • 删除上述参数。在我们的例子中 mysum x = (x +)
  • 重复,直到你没有更多的参数。这里 mysum = (+)

  • (我选择了一个简单的例子,对于更复杂的情况,你必须使用 flip 等)

    关于haskell - Haskell中函数组合的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6913093/

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