我了解到Monad.Reader实际上是一个函数的封装,即:
newtype Reader r a = Reader { runReader :: r -> a }
Run Code Online (Sandbox Code Playgroud)
这是Monad的一个例子,
instance Monad (Reader r) where
return a = Reader $ \_ -> a
m >>= k = Reader $ \r -> runReader (k (runReader m r)) r
Run Code Online (Sandbox Code Playgroud)
相比之下,我知道( - >)也是Monad,
instance Monad ((->) r) where
return = const
f >>= k = \ r -> k (f r) r
Run Code Online (Sandbox Code Playgroud)
从定义中可以看出它们实际上的行为完全相同.
那么它们在所有用途中都可以互换吗?不同这两个Monads的实际意义是什么?
Zet*_*eta 10
他们是一样的.
State,Writer并Reader受到Mark P. Jones的" 超载和高阶多态性函数式编程 "的启发,他在此定义Reader如下:
甲
Reader单子用于允许计算访问在一些封闭环境(由类型表示所保持的值r在下面定义).Run Code Online (Sandbox Code Playgroud)> instance Monad (r->) where > result x = \r -> x > x `bind` f = \r -> f (x r) r作为传递评论,值得注意的是,这两个函数只是组合逻辑的标准
K和S组合.
后来,他定义了(几乎)今天的MonadReader:
Reader monads:一类monad,用于描述咨询某些固定环境的计算:Run Code Online (Sandbox Code Playgroud)> class Monad m => ReaderMonad m r where > env :: r -> m a -> m a > getenv :: m r > instance ReaderMonad (r->) r where > env e c = \_ -> c e > getenv = id
getenv很简单ask,而且env是local . const.因此,这个定义已经包含了a的所有重要部分Reader.最终,琼斯定义了monad变换器ReaderT(BComp后向构图):
首先,定义两种不同形式的组合是有用的; 前锋(
FComp)和后退(BComp):Run Code Online (Sandbox Code Playgroud)> data FComp m n a = FC (n (m a)) > data BComp m n a = BC (m (n a))[省略Functor,Monad和OutOf实例]
Run Code Online (Sandbox Code Playgroud)> type ReaderT r = BComp (r ->)
因为StateT,WriterT和其他人有非变压器变体,所以有一个Reader r真正相同的逻辑是合乎逻辑的(->) r.
无论哪种方式,现在Reader,Writer并且State根据它们的变换器变体定义,并且您使用它们各自的Monad*类型类(MonadReader).
那么它们在所有用途中都可以互换吗?
是.
不同这两个Monads的实际意义是什么?
没有,除了它ReaderT实际上是一个monad变换器,这使事情变得更容易.