我正在浏览this source code用于学习。
在第 81 行我看到以下代码:
MaybeT . fmap Just $ locked .= False
我对函数组合的使用感到困惑,因此我将其加载到我的 repl 中并用函数应用程序替换它
MaybeT $ fmap Just $ locked .= False
我很惊讶这两段代码给出了准确的结果。
Control.Monad.State.Class.MonadState Game m => MaybeT m ()
事实上,我可以理解函数应用 ($)
如何生成此结果,但我对函数组合 (.)
如何生成此结果感到困惑。这两个函数的签名不同,我认为如果其中一个函数替换另一个函数,它们显然应该产生不同的结果。
:t (.) :: (b -> c) -> (a -> b) -> a -> c
:t ($) :: (a -> b) -> a -> b
有人可以向我解释一下为什么 ($)
和 (.)
在这种情况下可以互换。
最佳答案
它们不可互换。
你拥有的是
MaybeT . fmap Just $ locked
MaybeT $ fmap Just $ locked -- you had `dead` here
但由于运算符优先级,它实际上被解析为
(MaybeT . fmap Just) locked -- and
MaybeT $ fmap Just locked
.
和 $
在这里参与不同的结构表达式。可互换意味着您可以替换
(MaybeT . fmap Just) locked -- with
(MaybeT $ fmap Just) locked
显然事实并非如此。
因此,在相同表达式中将 .
替换为 $
会产生不同的结果,正如您所期望的那样。同时两个不同表达式碰巧产生相同的结果。这没什么奇怪的,表达式总是被简化为等价的不同表达式。
关于Haskell 函数组合 (.) 与函数应用 ($),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59503058/