- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图采取例如ExceptT a (StateT A M)
, 对于某些具体类型 A
和单子(monad)M
,并将它们包装到我的新自定义单子(monad)中。
首先我确定StateT A M
经常出现在其他上下文中,因此我决定最好将其单独包装在 monad M1
然后包装 ExceptT a M1
进入 M2
.
所需的属性是使 M1
和 M2
MonadState
的实例和 M
的类(假设它被称为 MyMonadClass
)。还有M2
应该是 MonadError
的一个实例.
首先,我从简单的类型同义词开始:
type MyState = StateT A M
type MyBranch a = ExceptT a MyState
instance MonadState A (MyState)
似乎不是正确的语法。我以为我必须创建
newtype MyState' a = StateT a M
然后
type MyState = MyState A
(让我们不要在不必要的地方使用语言扩展)。
newtype
我开始失去与
StateT A M
的连接和
ExceptT ...
类型。
newtype MyState' s a = MyState' { runMyState :: s -> (s, a) }
type MyState = MyState' A
newtype MyBranch e a = MyBranch { runMyBranch :: MyState (Either e a) }
最佳答案
正常模式是为您的完整变压器堆栈定义一个新类型。
data A = A
data E = E
newtype MyBranchT m a = MyBranchT { getMyBranchT :: ExceptT E (StateT A m) a }
GeneralizedNewtypeDeriving
获取所有各种 monad 类的实例。
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- base
import Control.Applicative
import Control.Monad
-- transformers
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Control.Monad.Trans.Except
import Control.Monad.Trans.State.Lazy
-- mtl classes
import Control.Monad.Cont.Class
import Control.Monad.Error.Class
import Control.Monad.Reader.Class
import Control.Monad.State.Class
import Control.Monad.Writer.Class
data A = A
data E = E
newtype MyBranchT m a = MyBranchT { getMyBranchT :: ExceptT E (StateT A m) a }
deriving (Functor, Applicative, Monad, MonadIO, -- classes from base and transformers
{- Alternative, MonadPlus, -} -- if E is a monoid
MonadState A, MonadError E, -- classes from mtl that MyBranchT provides
MonadCont, MonadReader r, MonadWriter w) -- classes from mtl that might be available from m
MonadTrans
手工实例。
lift
总是只是
lift
堆栈中的每个变压器一次。
instance MonadTrans MyBranchT where
lift = MyBranchT . lift . lift
X
您还可以自行定义一个新的
MonadX
那些能力的类,写
MonadX
如果可能,每个 monad 转换器(
StateT
、
ExceptT
、
ContT
等)的实例,并导出
MonadX
变压器堆栈的实例 (
MyBranchT
)。
MyBranchT Identity
创建一个类型同义词。和函数到
runMyBranchT
和
runMyBranch
import Data.Functor.Identity
type MyBranch a = MyBranchT Identity a
runMyBranchT :: MyBranchT m a -> A -> m (Either E a, A)
runMyBranchT mb s = runStateT (runExceptT (getMyBranchT mb)) s
runMyBranch :: MyBranch a -> A -> (Either E a, A)
runMyBranch mb s = runIdentity $ runMyBranchT mb s
关于haskell - 整理 Monads - 将 monad 转换器的应用程序转变为新型 monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32572152/
在尝试为 ContT monad 转换器建立一些直觉时,我(也许并不奇怪)发现自己很困惑。问题在于 shiftT 操作,它似乎没有做任何有用的事情。 首先是一个简单的例子,说明如何使用它 shiftT
我有 Item 1 Item 2 我想要切换 var elements = document.getElementsByName('R
执行此操作的最快方法是什么?左边括号中的变量返回 bool 值,它们表示窗口大小范围。 (例如,o1281 为 1281 及以上屏幕返回 true,o1025 为 1025 及以上屏幕返回 true,
我对编程还很陌生,但我的任务是维护一些由前员工创建的应用程序。我有一个 ?: 声明现在需要处理的不仅仅是真或假声明,但我不确定如何去做。有问题的代码是: MailDomainContext m
为什么 GMT-0400 在 1989 年之前转变为 GMT-0500? > new Date('1989-04-02T23:01:14.52Z') Sun Apr 02 1989 19:01:14
我们有一堆代理对(或 2 字节 utf8?)字符,例如 ��,这是作为 2 个字符存储为 UTF8 的祈祷 watch 情符号。在浏览器中呈现时,此字符串呈现为两个 ?? 例子:�� 我需要使用 ph
我知道我可以将字符串格式的 unixTime 转换为本地时间的毫秒val currentTimeMillis = serverTimeDateFormat.parse(iso8601).time 我想
我是一名优秀的程序员,十分优秀!