- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
抱歉,如果这个问题看起来有点微不足道……它不适合我。我很高兴地编写了以下 monad:
type SB i a = ReaderT ( AlgRO i ) (State ( AlgState i ) ) a
这是一个表现良好的单子(monad)。 ReaderT 是一个 monad 转换器,State 是 State monad,AlgRO 和 AlgState 是 i 中参数化的数据类型,分别表示可变和只读状态。现在,如果我想用 newtype 制作一个简洁的 monad 转换器,如下所示:
newtype SbT m i a = SbT {
runSbT:: m ( SB i a )
}
我应该如何进行?我什至无法设法将绑定(bind)方法(Monad 类型类)组合在一起,更不用说“提升”(MonadTrans)了……我想自动推导可能会有所帮助,但我想了解它在这种情况下是如何工作的。
提前致谢。
最佳答案
我不认为 SbT
的定义就是你想要的。这定义了仿函数组合,并假设 m
参数是 Functor
或Applicative
,这应该保留这些属性。但一般来说,这样的组合不会从另外两个单子(monad)中创建一个新的单子(monad)。请参阅this question了解有关该主题的更多信息。
那么,您如何创建您想要的 monad 转换器呢?虽然 monad 不能直接组合,但 monad transformers 可以组合。因此,要从现有的变压器中构建一个新的变压器,您本质上只需要为该组合命名即可。这与 newtype
不同你有,因为你正在应用 m
直接,而不是将其传递到变压器堆栈。
关于定义 monad 变压器需要记住的一件事是它们必然以某些方式“向后”工作——当你将复合变压器应用于 monad 时,“最里面的”变压器首先受到影响,然后它产生的转换后的单子(monad)是下一个变压器要使用的,等等。请注意,这与将组合函数应用于参数时获得的顺序没有任何不同,例如(f . g . h) x
将参数提供给 h
首先,尽管 f
是组合中的“第一个”函数。
好吧,所以你的复合变压器需要获取它所应用的 monad 并将其传递给最里面的变压器,也就是,呃......哎呀,结果是 SB
已经应用于一个 monad。难怪这不起作用。我们需要首先删除它。它在哪里?不是State
--我们可以删除它,但我们不想这样做,因为它是您想要的一部分。嗯,但是等等——State
是什么?再次定义为?哦,是的:
type State s = StateT s Identity
啊哈,我们开始了。让我们来了解一下Identity
离开那里。我们从您当前的定义出发:
type SB i a = ReaderT ( AlgRO i ) (State ( AlgState i ) ) a
等效形式:
type SB i a = ReaderT ( AlgRO i ) ( StateT ( AlgState i ) Identity ) a
然后我们把懒惰的人踢出去:
type SB' i m a = ReaderT ( AlgRO i ) ( StateT ( AlgState i ) m ) a
type SB i a = SB' i Identity a
但现在SB'
看起来可疑地像一个 monad 转换器的定义,并且有充分的理由,因为它确实如此。所以我们重新创建newtype
包装器,然后扔一些实例:
newtype SbT i m a = SbT { getSB :: ReaderT ( AlgRO i ) ( StateT ( AlgState i ) m ) a }
instance (Functor m) => Functor (SbT i m) where
fmap f (SbT sb) = SbT (fmap f sb)
instance (Monad m) => Monad (SbT i m) where
return x = SbT (return x)
SbT m >>= k = SbT (m >>= (getSB . k))
instance MonadTrans (SbT i) where
lift = SbT . lift . lift
runSbT :: SbT i m a -> AlgRO i -> AlgState i -> m (a, AlgState t)
runSbT (SbT m) e s = runStateT (runReaderT m e) s
需要注意的几点:runSbT
这里的函数不是字段访问器,而是我们所知的堆栈中每个变压器的组合“运行”函数。同样,lift
函数必须为两个内部变压器提升一次,然后添加最后的 newtype
wrapper 。这两者都使它作为单个 monad 转换器工作,隐藏了它实际上是一个复合体的事实。
如果您愿意,为 MonadReader
编写实例应该很简单和MonadState
同样,通过提升组合变压器的实例。
关于haskell - 将 monad 组合抽象为变压器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7413545/
我有一个 mysql 表,其中包含一些随机数字组合。为简单起见,以下表为例: index|n1|n2|n3 1 1 2 3 2 4 10 32 3 3 10 4 4
我有以下代码: SELECT sdd.sd_doc_classification, sdd.sd_title, sdd.sd_desc, sdr.sd_upl
如果我有两个要合并的数据框 Date RollingSTD 01/06/2012 0.16 01/07/2012 0.18 01/08/2012 0.17 01/09/20
我知道可以使用 lein ring war 创建一个 war 文件,但它似乎仍然包含码头依赖项。当我构建 war (并在 tomcat 上部署)时,有没有办法排除码头依赖项? 如果我根本不能做这件事,
维基百科关于封装的文章指出: “封装还通过防止用户将组件的内部数据设置为无效或不一致的状态来保护组件的完整性” 我在一个论坛上开始讨论封装,在那里我问你是否应该始终在 setter 和/或 gette
对于我使用的组合框内的复选框: AOEDComboAssociationName = new Ext.form.ComboBox({ id: 'AOEDComboAssociationName',
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: How do I combine LINQ expressions into one? public boo
如何在 rust 中找到排列或组合的数量? 例如C(10,6) = 210 我在标准库中找不到这个函数,也找不到那里的阶乘运算符(这就足够了)。 最佳答案 以@vallentin 的回答为基础,可以进
我有一个复杂的泛型类型用例,已在下面进行了简化 trait A class AB extends A{ val v = 10 } trait X[T<:A]{ def request: T }
如何使用 Hibernate 限制来实现此目的? (((A='X') and (B in('X',Y))) or ((A='Y') and (B='Z'))) 最佳答案 思考有效 Criteria c
我一定会在我的一个项目中使用谷歌图表。我需要的是,显示一个条形图,并且在条形图中,与每个条形相交的线代表另一个值。如果您查看下面的 jsfiddle,您会发现折线图仅与中间的条形图相交,并继续向其他条
只是一个简单的问题,我也很想得到答案,因为我不能百分百理解 Javascript 示例:假设您提示用户输入名称。够简单吧?但是你有一个数组,上面写着一些名字(其中之一就是),基本上就是我到目前为止所说
我试图通过 Haskell 理解函数式编程,但在处理函数组合时遇到了很多麻烦。 其实我有这两个功能: add:: Integer -> Integer -> Integer add x y = x
我正在寻找一种在 Realm 查询中组合 AND 和 OR 的方法。 这是我的课: class Event extends RealmObject { String id; String
例如,我有一个包含 5 个元素的哈希: my_hash = {a: 'qwe', b: 'zcx', c: 'dss', d: 'ccc', e: 'www' } 我的目标是每次循环哈希时都返回,但没
我是Combine 的新手,我想得到一个看似简单的东西。假设我有一个整数集合,例如: let myCollection = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 我想以例如 0
关于“优先组合而不是继承”的问题,我的老师是这样说的: 组合:现有类成为新类的组件 转发:新类中的每个实例方法,在现有类的包含实例上调用相应的方法并返回结果 包装器:新类封装了现有的 这三个概念我不是
我正在尝试将单个整数从 ASCII 值转换为 0 和 1。相关代码如下所示: int num1 = bin.charAt(0); int num2 = bin.charAt(1);
这个问题已经有答案了: What is a NullPointerException, and how do I fix it? (12 个回答) 已关闭 7 年前。 我经常看到“嵌套”类中的非静态变
我尝试合并两个数据集(DataFrame),如下所示: D1 = pd.DataFrame({'Village':['Ampil','Ampil','Ampil','Bachey','Bachey',
我是一名优秀的程序员,十分优秀!