haskell中的单子变压器是独特的吗?
有几个问题(例如io“> this 和 this )询问Haskell(IO除外)中的每个单子是否都有相应的单子变压器。现在我想问一个补充问题。每个单子都完全有一个变压器(或在IO中没有一个变压器),还是可以有一个以上的变压器?
反例将是两个单子变压器,当应用于Monad的身份时,将产生相同行为的单调,但是当应用于其他单调时会产生不同的行为单调。如果答案是单子可以拥有多个变压器,我想拥有一个尽可能简单的haskell示例。这些实际上不必是有用的变压器(尽管这很有趣)。
链接的问题中的一些答案似乎表明单子可能有多个变压器。但是,除了类别的基本定义之外,我不知道太多的类别理论,因此我不确定它们是否是这个问题的答案。
There have been a couple of questions (e.g. this and this) asking whether every monad in Haskell (other than IO) has a corresponding monad transformer. Now I would like to ask a complementary question. Does every monad have exactly one transformer (or none as in the case of IO) or can it have more than one transformer?
A counterexample would be two monad transformers that would produce monads behaving identically when applied to the identity monad would but would produce differently behaving monads when applied to some other monad. If the answer is that a monad can have more than one transformer I would like to have a Haskell example which is as simple as possible. These don't have to be actually useful transformers (though that would be interesting).
Some of the answers in the linked question seemed to suggest that a monad could have more than one transformer. However, I don't know much category theory beyond the basic definition of a category so I wasn't sure whether they are an answer to this question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是一个反例的想法。我们知道,通常,Monad不会构成...但是我们也知道,如果有适当的
交换>交换
操作,您可以撰写它们[1]!让我们为可以与自己交换的单子上课。然后,我们可以构建一个与自身组成单元的单子变压器,这样:
希望应该很明显
pure
and(< $>)
do。我不会定义(>> =)
,我将定义JOIN
,因为我认为这有点明显。(>> =)
可以从中得出。我尚未检查
lift
遵守monadtrans
所有swap> swap
实例的法律,但是我确实检查了它们是否Identity
和也许
。现在,我们已经
表明
Identityt
不是生产Identity
的唯一单调变压器。[1]由马克·琼斯(Mark P.
Here's one idea for a counterexample to uniqueness. We know that in general, monads don't compose... but we also know that if there's an appropriate
swap
operation, you can compose them[1]! Let's make a class for monads that can swap with themselves.Then we can build a monad transformer that composes a monad with itself, like so:
Hopefully it should be obvious what
pure
and(<$>)
do. Rather than defining(>>=)
, I'll definejoin
, as I think it's a bit more obvious what's going on;(>>=)
can be derived from it.I haven't checked that
lift
obeys theMonadTrans
laws for allSwap
instances, but I did check them forIdentity
andMaybe
.Now, we have
which shows that
IdentityT
is not a unique monad transformer for producingIdentity
.[1] Composing monads by Mark P. Jones and Luc Duponcheel
身份单元至少具有两个单元变压器:身份单元变压器和 codsente monad变压器。
实际上,考虑
codsential Identity
,forall r。 (a - &gt; r) - &gt; r
是a
的同构。这些单子变压器完全不同。一个示例是,“括号”可以定义为
codsenty
的单声道操作:而将该签名转换为
Identityt
并没有说明其他示例,从而可以从尽管我还没有看到一般方案,但延续/codsenty monad的变体。
状态单元对应于状态单元变压器,以及
codsente
和readert
的组成:列表monad至少对应三个单核变压器,而不是包括错误的一个
:可以在包装中分别找到前两个(也以管道),
and
The identity monad has at least two monad transformers: the identity monad transformer and the codensity monad transformer.
Indeed, considering
Codensity Identity
,forall r. (a -> r) -> r
is isomorphic toa
.These monad transformers are quite different. One example is that "bracket" can be defined as a monadic action in
Codensity
:whereas transposing that signature to
IdentityT
doesn't make much senseOther examples can be found similarly from variants of the continuation/codensity monad, though I don't see a general scheme yet.
The state monad corresponds to the state monad transformer and to the composition of
Codensity
andReaderT
:The list monad corresponds to at least three monad transformers, not including the wrong one:
The first two can be found respectively in the packages list-t (also in an equivalent form in pipes),
and logict.
一个单子有两个不等变压器的单个例子:“选择”单元。
单子不是众所周知,但有些论文提到了。这是一个涉及一些论文的软件包:
https://hackage.haskell.org/package/transformers-0.6.0.4/docs/control-monad-monad-trans-select.html
该软件包实现了一个变压器:
但是存在第二个变形金刚:证明法律:
证明法律法律 :因为这个变压器更加困难,但我做到了。
第二个变压器的一个优点是它在
m
中是协变量的,因此可以定义HOIST
函数:第二个变压器是“完全特色”,具有所有提升和“提升”。第一个变压器尚未完全出现。例如,您无法定义
blift :: Sel ra-&gt; SELT RM A
。换句话说,您不能将sel
的单声道计算嵌入selt
中,就像您无法使用Continuation Monad和Codmenta Monad这样做。但是,使用
SEL2T
变压器,所有升力都存在,您可以将sel
计算嵌入到sel2t
中。此示例显示了一个带有两个变压器的单子,而无需以任何方式使用码头密度构造。
There is another example of a monad that has two inequivalent transformers: the "selection" monad.
The monad is not well known but there are papers that mention it. Here is a package that refers to some papers:
https://hackage.haskell.org/package/transformers-0.6.0.4/docs/Control-Monad-Trans-Select.html
That package implements one transformer:
But there exists a second transformer:
Proving laws for this transformer is more difficult but I have done it.
An advantage of the second transformer is that it is covariant in
m
, so thehoist
function can be defined:The second transformer is "fully featured", has all lifts and "hoist". The first transformer is not fully featured; for example, you cannot define
blift :: Sel r a -> SelT r m a
. In other words, you cannot embed monadic computations fromSel
intoSelT
, just like you can't do that with the Continuation monad and the Codensity monad.But with the
Sel2T
transformer, all lifts exist and you can embedSel
computations intoSel2T
.This example shows a monad with two transformers without using the Codensity construction in any way.