繁体   English   中英

感兴趣的是( - >)作为monad和functor的实例

[英]Intrigued by (->) as instances of monad and functor

当我在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或functor,但是(->) r是。 MonadFunctor类型都有类型* -> * ,因此它们只需要一个类型参数。

这意味着(->) r fmap看起来像

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

这也被称为

fmap g func = g . func

这只是正常的功能构成! 当您通过func fmap g时,可以通过对其应用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的隐式参数应用于绑定右侧的每个函数。 因此,如果将1.0传递给f ,它会将值2 * 1.0绑定到x1并将2 + 1.0绑定到x2 ,然后返回(x1, x2) 它确实可以很容易地将单个参数应用于许多子表达式。 这个功能相当于

f' x = (2 * x, 2 + x)

为什么这有用? 一个常见的用途是Reader monad,它只是一个围绕(->) r的newtype包装器。 Reader monad使您可以轻松地在应用程序中应用静态全局配置。 你可以写代码

myApp :: Reader Config ()
myApp = do
    config <- ask
    -- Use config here
    return ()

然后使用runReader myApp initialConfig运行应用程序。 您可以轻松地在Reader Config monad中编写操作,组合它们,将它们链接在一起,并且所有这些操作都可以访问全局的readonly配置。 此外,还有一个配套的ReaderT monad变换器,允许您将其构建到变换器堆栈中,让您拥有非常复杂的应用程序,可以轻松访问静态配置。

我认为如果Haskell总是允许类型操作符部分,那会有点混乱:

data a->b

instance Monad (r -> )

看起来更自然。

简而言之:我发现考虑特殊情况Monad (Bool -> )非常有帮助,它基本上是一个双元素容器类型。 它有两个要素

\case
  False -> elem1
  True -> elem2

因此,您可以考虑与列表相同的仿函数实例:映射“所有包含的元素”。

applicative和monad实例有点不同,它可能有助于使“容器转换”显式:

data Pair a = Pair a a

instance Functor Pair where
  fmap f (Pair a b) = Pair (f a) (f b)

instance Monad Pair where
  return a = Pair a a
  join (Pair (Pair a _) (Pair _ b))
      = Pair       a            b

您可以查看自己,例如http://hackage.haskell.org/package/base-4.6.0.1/docs/src/GHC-Base.html

从那里复制:

instance Functor ((->) r) where
    fmap = (.)

instance Monad ((->) r) where
    return = const
    f >>= k = \ r -> k (f r) r

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM