我已经学习 Haskell 几个星期了(只是为了好玩),刚刚观看了 Brian Beckman介绍 monad的精彩视频。他激励 monad 需要创建一个更通用的组合运算符。按照这个思路,如果我有两个功能:
f :: a -> b
g :: b -> c
Run Code Online (Sandbox Code Playgroud)
组合运算符应该满足
h = g . f :: a -> c
Run Code Online (Sandbox Code Playgroud)
由此我可以推断出正确的.运算符类型:
(.) : (b -> c) -> (a -> b) -> (a -> c)
Run Code Online (Sandbox Code Playgroud)
说到 monad,假设我有两个功能:
f :: a -> m b
g :: b -> m c
Run Code Online (Sandbox Code Playgroud)
在我看来,自然的选择是定义一个通用的组合运算符,其工作方式如下:
h = f >>= g :: a -> m c
Run Code Online (Sandbox Code Playgroud)
在这种情况下,>>=运算符的类型签名为:
(>>=) :: (a -> …Run Code Online (Sandbox Code Playgroud) Haskell的新手,我正试图找出这个Monad的东西.monadic绑定运算符 - >>=具有非常奇特的类型签名:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)
为了简化,我们替换Maybe为m:
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
Run Code Online (Sandbox Code Playgroud)
但请注意,该定义可以用三种不同的方式编写:
(>>=) :: Maybe a -> (Maybe a -> Maybe b) -> Maybe b
(>>=) :: Maybe a -> ( a -> Maybe b) -> Maybe b
(>>=) :: Maybe a -> ( a -> b) -> Maybe b
Run Code Online (Sandbox Code Playgroud)
在这三个中,中心的一个是最不对称的.但是,据我所知,如果我们想避免(LYAH称为样板代码),第一个有点无意义.但是,接下来的两个,我更喜欢最后一个.对于 …
如果我有两个单子m和n,和n是穿越,我一定有复合m-over- n单子?
更正式的,这就是我的想法:
import Control.Monad
import Data.Functor.Compose
prebind :: (Monad m, Monad n) =>
m (n a) -> (a -> m (n b)) -> m (n (m (n b)))
mnx `prebind` f = do nx <- mnx
return $ do x <- nx
return $ f x
instance (Monad m, Monad n, Traversable n) => Monad (Compose m n) where
return = Compose . return . return
Compose mnmnx >>= f …Run Code Online (Sandbox Code Playgroud) 在“ 伴随函子”中确定monad变压器,但升降机在哪里?,西蒙C向我们展示了该结构...
newtype Three u f m a = Three { getThree :: u (m (f a)) }
Run Code Online (Sandbox Code Playgroud)
...,作为那里讨论的答案,可以给instance Adjunction f u => MonadTrans (Three u f)(附加语将其提供为AdjointT)。因此,任何Hask / Hask附加都将导致monad变压器。尤其StateT s是通过(,) s和之间的临时连接以这种方式产生(->) s。
我的后续问题是:此构造是否可以推广到其他monad变压器?是否有办法从合适的附件中从变压器包中衍生出其他变压器?
Meta备注:我的回答最初是为Simon C的问题写的。我选择将其分解为一个自我回答的问题,因为在重读该问题时,我注意到我所谓的回答与该评论中的讨论有关,而与问题本身无关。这个问答可能还会跟进另外两个密切相关的问题:是否有一个单声道没有相应的单声道转换器(IO除外)?并且具有可遍历的任意单子的组合是否总是单子?
我正在深入研究 Haskell这本书,我注意到以下代码示例:
withReader :: (r' -> r) -> Reader r a -> Reader r' a
Run Code Online (Sandbox Code Playgroud)
这看起来像contramap。Control.Monad.Reader和之间有什么关系Data.Functor.Contravariant?