【发布时间】:2016-04-28 05:19:50
【问题描述】:
我查看了past discussion,但不明白为什么任何答案实际上都是正确的。
适用
<*> :: f (a -> b) -> f a -> f b
单子
(>>=) :: m a -> (a -> m b) -> m b
所以,如果我做对了,则声称不能仅通过假设 <*> 的存在来编写 >>=
好吧,假设我有<*>。
我想创建>>=。
所以我有f a。
我有f (a -> b)。
现在,当您查看它时,f (a -> b) 可以写成 (a -> b)(如果某物是 x、y、z 的函数 - 那么它也是 x、y 的函数)。
所以从<*>的存在我们得到(a -> b) -> f a -> f b,又可以写成((a -> b) -> f a) -> f b,也可以写成(a -> f b)。
所以我们有f a,我们有(a -> f b),我们知道<*> 会产生f b,所以我们得到:
f a -> (a -> f b) -> f b
这是一个单子。
实际上,用更直观的语言:在实现<*>时,我从f(a -> b)中提取(a -> b),从f a中提取a,然后在a上应用(a -> b)并得到b,我用f 包装最终得到f b。
所以我几乎用同样的方法来创建>>=。在a 上应用(a -> b) 并得到b 后,再执行一步并用f 包裹它,所以我返回f b,因此我知道我有一个函数(a -> f b)。
【问题讨论】:
-
Now when you think about it, f(a -> b) can be written as (a -> b)这不是真的,没有Applicative f => f (a -> b) -> (a -> b)类型的函数。简单地说,如果你的理论是正确的,那么通过 curry howard 同构,你可以编写函数来证明这个理论——所以写它 (forall f a b . Applicative f => f a -> (a -> f b) -> f b),看看为什么它实际上是不可能的。最后,即使你可以构造一个f a -> (a -> f b) -> f b类型的函数,你仍然必须证明它满足 Monad 定律。 -
@rapt
g是什么?f是什么?如果你只是假设这些函数存在而不证明它,那么当然,你可以证明任何东西。 -
@rapt 我认为您混淆了值级别和类型级别。您似乎在价值级别描述功能,但您指的是类型级别的东西。这里的
f是一个类型构造函数,由另一种类型参数化,而不是值级函数。 -
“如果某物是 x、y、z 的函数——那么它也是 x、y 的函数”——撇开
f (a -> b)不说“f、a 和 b 的函数” ",您的主张无效。您需要拥有 a z 才能从 x、y 和 z 的函数中获取 x 和 y 的函数。 -
实际上恰恰相反。如果您需要提供函数
x -> y -> z -> c(x、y 和 z 的函数,我将其返回称为 c),并且您有一个函数x -> y -> c,您可以通过编写一个函数来生成所需的函数忽略z并调用您拥有的函数。如果没有更多信息,反过来是不可能的。
标签: haskell functional-programming monads functor applicative