win*_*zki 16 monads haskell functional-programming monad-transformers
Monad变换器以所有标准monad(Reader,Writer,State,Cont,List等)而闻名,但这些monad变换器中的每一个都以稍微不同的方式工作.在给定具有monad实例的类型构造函数的定义的情况下,没有用于构造monad变换器的通用方法或公式.因此,不能保证根据某些任意业务要求设计的monad数据类型将具有monad变换器.有没有这样一个明确的例子?
另一个问题解释了两个monad的仿函数组合不一定是monad.另见这个问题.这些例子没有回答当前的问题 - 它们仅仅说明了没有构造单子变压器的一般方法的问题.这些例子表明,给定两个单子M和N,我们有时会发现M(N a)是单子,有时N(M a)是单子,有时也不是单子.但这既没有说明如何为M或N构造monad变换器,也没有表明它是否存在.
另一个问题的答案认为,IO单子不能有一个单子转换,因为如果它有一个IOT,我们可以申请IOT到List,然后抬起空列表(lift [])到生成的单子就必须撤消副作用的进行"早期" IO monad.这个论点是基于IOmonad"实际上执行"可能无法撤消的副作用的想法.但是,IOmonad不是显式类型构造函数.
在明确给出monad类型的每个例子中,可以以某种方式找到monad变换器, - 有时需要一定的独创性.例如,最近发现ListT存在于Haskell库中的变换器以微妙的方式发生错误,但最终通过更改定义来解决问题.ListT
没有变换器的monad的标准示例是monad,例如IO,实际上不是由显式类型构造函数定义的 - IO是库以某种方式在低级别定义的不透明"魔术"类型.很明显,无法将IO纯函数赋予monad实例定义为显式类型构造函数.该IO示例显示,如果我们允许monad实例包含具有不纯副作用的隐藏低级代码,则monad转换器可能无法存在.所以,让我们将注意力限制在使用纯函数实现的monad上.
似乎没有一种算法可以从monad的源代码中自动导出monad变换器.我们甚至知道这总是可能的吗?
为了让我更清楚一个monad的"明确例子"我的意思:假设我声称
 type Q u v a = ((u -> (a, Maybe a)) -> v) -> u -> (a, Maybe a)
可以有一个合法的Monad实例相对于所述类型参数a,以及我产生的源代码的一个实施Monad例如Q u v作为纯的功能return和join.这样,我们知道,Q u v有一个单子转换QT u v这样QT u v Id就相当于Q u v,和单子变压器的法律持有?那么我们知道如何QT明确构建吗?我不.
要决定这个问题,我们需要
type F a = r -> Either (a, a) (a, a, Maybe a)和monad实例的实现,找到monad变换器的代码; 让我们限制自己输入由任意组合->,元组和Either简单组成的构造函数; 要么type F a = r -> Either (a, a, a) (a, a, Maybe a)或什么的,这样,这是一个合法的Monad,有Monad纯函数给出的实例,但我们可以证明是F没有单子转换.这不是答案,但对于评论来说太大了。我们可以写
{-# LANGUAGE GeneralizedNewtypeDeriving
  , DeriveFunctor #-}
import Control.Monad.Free
-- All the IO primops you could ever need
data IOF a = PutStrLn String a
           | GetLine (String -> a)
           deriving Functor
newtype MyIO a = MyIO {unMyIO :: Free IOF a}
  deriving (Functor, Applicative, Monad)
但我们实际上可以用它来制作一个 monad 转换器:
import Control.Monad.Trans.Free
newtype IOT m a = IOT {unIOT :: FreeT IOF m a}
  deriving (Functor, Applicative, Monad, MonadTrans)
所以我真的不认为 EvenIO被排除在外,尽管这种情况下的同构不是“内部的”。
| 归档时间: | 
 | 
| 查看次数: | 390 次 | 
| 最近记录: |