gpt4 book ai didi

haskell - 被 (->) 作为 monad 和 functor 的实例所吸引

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

我对 (->) 很感兴趣当我查找有关 (->) 的信息时在 ghci 中。它说,

data (->) a b -- Defined in `GHC.Prim`

到目前为止一切都很好,但是当它说 -
instance Monad ((->) r) -- Defined in `GHC.Base`
instance Functor ((->) r) -- Defined in `GHC.Base`

这意味着什么?为什么 GHC 将其定义为 Monad 的实例,而 Functor 定义为 (->) ?

最佳答案

一开始可能有点困惑,但要记住的一个重要概念是 (->)不是单子(monad)或仿函数,而是 (->) r是。 MonadFunctor类型都有 * -> * ,所以他们只期望一个类型参数。

这意味着 fmap对于 (->) r好像

fmap g func = \x -> g (func x)

这也被称为
fmap g func = g . func

这只是正常的功能组合!当你 fmap g超过 func ,您可以通过应用 g 来更改输出类型给它。在这种情况下,如果 func类型为 a -> b , g必须有类似 b -> c 的类型.
Monad实例更有趣。它允许您在应用程序发生“之前”使用函数应用程序的结果。帮助我理解的是看到一个例子
f :: Double -> (Double,Double)
f = do
x1 <- (2*)
x2 <- (2+)
return (x1, x2)

> f 1.0
(2.0, 3.0)

这样做是将隐式参数应用于 f绑定(bind)到右侧的每个函数。所以如果你传入 1.0f ,它将绑定(bind)值 2 * 1.0x1并绑定(bind) 2 + 1.0x2 ,然后返回 (x1, x2) .它确实很容易将单个参数应用于许多子表达式。这个函数相当于
f' x = (2 * x, 2 + x)

为什么这很有用?一种常见的用法是 Reader monad,它只是 (->) r 的新类型包装器. Reader monad 可以很容易地在应用程序中应用静态全局配置。你可以编写如下代码
myApp :: Reader Config ()
myApp = do
config <- ask
-- Use config here
return ()

然后你用 runReader myApp initialConfig 运行你的应用程序。 .您可以在 Reader Config 中轻松编写操作monad,组合它们,将它们链接在一起,它们都可以访问全局的只读配置。另外还有一个小伙伴 ReaderT monad 转换器,它允许您将其构建到您的转换器堆栈中,让您拥有可以轻松访问静态配置的非常复杂的应用程序。

关于haskell - 被 (->) 作为 monad 和 functor 的实例所吸引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21026021/

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