有几个问题(例如,这和这)在Haskell (IO以外)的每个单播中是否都有相应的单台转换器。现在我想提出一个补充问题。是每个单机都有一个变压器(或者没有一个变压器,就像IO那样),还是可以有多个变压器?
一个反例将是两个单台变压器,当应用到身份单端时会产生行为相同的单片,但如果应用到其他单模上,则会产生不同的行为单点。如果答案是一个单一的可以有多个变压器,我想有一个Haskell的例子,这是尽可能简单的。这些并不一定是真正有用的变压器(虽然这会很有趣)。
链接问题中的一些答案似乎表明,一台单机可能有多台变压器。然而,除了范畴的基本定义之外,我不知道更多的范畴理论,所以我不确定它们是否是这个问题的答案。
发布于 2022-06-03 19:36:14
标识单元至少有两个单一变压器:标识单变压器和共密度单片变压器。
newtype IdentityT m a = IdentityT (m a)
newtype Codensity m a = Codensity (forall r. (a -> m r) -> m r)实际上,考虑到Codensity Identity,forall r. (a -> r) -> r与a是同构的。
这些单台变压器完全不同。例如,可以将“括号”定义为Codensity中的一元操作。
bracket :: Monad m => m () -> m () -> Codensity m ()
bracket before after = Codensity (\k -> before *> k () *> after)然而,将该签名转换到IdentityT并没有多大意义
bracket :: Monad m => m () -> m () -> IdentityT m () -- cannot implement the same functionality其他的例子也可以从延拓/共密度monad的变体中找到,尽管我还没有看到一般的方案。
状态单模对应于状态单端变压器以及Codensity和ReaderT的组成。
newtype StateT s m a = StateT (s -> m (s, a))
newtype CStateT s m a = CStateT (Codensity (ReaderT s m) a)列表单片对应至少三个单台变压器,但不包括错误的变压器:
newtype ListT m a = ListT (m (Maybe (a, ListT m a))) -- list-t
newtype LogicT m a = LogicT (forall r. (a -> m r -> m r) -> m r -> m r) -- logict
newtype MContT m a = MContT (forall r. Monoid r => (a -> m r) -> m r))发布于 2022-06-03 18:09:30
这里有一个关于唯一性的反例子的想法。我们知道在一般情况下,单簧管不构成..。但是我们也知道,如果有一个适当的swap操作,您可以编写them1!让我们为可以与自己交换的monads创建一个类。
-- | laws (from [1]):
-- swap . fmap (fmap f) = fmap (fmap f) . swap
-- swap . pure = fmap pure
-- swap . fmap pure = pure
-- fmap join . swap . fmap (join . fmap swap) = join . fmap swap . fmap join . swap
class Monad m => Swap m where
swap :: m (m a) -> m (m a)
instance Swap Identity where swap = id
instance Swap Maybe where
swap Nothing = Just Nothing
swap (Just Nothing) = Nothing
swap (Just (Just x)) = Just (Just x)然后,我们可以构建一个单台变压器,它可以自己组成一个单台,如下所示:
newtype Twice m a = Twice (m (m a))希望pure和(<$>)所做的事情应该是显而易见的。我将定义(>>=),而不是定义join,因为我认为它所发生的事情更加明显;(>>=)可以从它派生出来。
instance Swap m => Monad (Twice m) where
join = id
. Twice -- rewrap newtype
. fmap join . join . fmap swap -- from [1]
. runTwice . fmap runTwice -- unwrap newtype
instance MonadTrans Twice where lift = Twice . pure我没有检查lift是否对所有Swap实例都遵守了MonadTrans定律,但我确实检查了它们的Identity和Maybe。
现在,我们
IdentityT Identity ~= Identity ~= Twice Identity
IdentityT Maybe ~= Maybe !~= Twice Maybe这表明IdentityT并不是生产Identity的唯一单变压器。
由Mark P. Jones和Luc Duponcheel创作的单曲
发布于 2022-10-01 16:54:43
还有另一个例子,一个单一的,有两个不平等的变压器:“选择”单。
type Sel r a = (a -> r) -> a这个单子并不为人所知,但有一些报纸提到了它。这是一个参考一些文件的包裹:
https://hackage.haskell.org/package/transformers-0.6.0.4/docs/Control-Monad-Trans-Select.html
该包实现了一个转换器:
type SelT r m a = (a -> m r) -> m a但是有第二个变压器:
type Sel2T r m a = (m a -> r ) -> m a证明这台变压器的法律比较困难,但我已经做到了。
第二个转换器的一个优点是它在m中是协变的,因此可以定义hoist函数:
hoist :: (m a -> n a) -> Sel2T r m a -> Sel2T r n a第二个变压器是“全功能”,有所有的电梯和“提升机”。第一个转换器功能不全;例如,您不能定义blift :: Sel r a -> SelT r m a。换句话说,不能将Sel中的一元计算嵌入到SelT中,就像不能用连续单元和共密度元嵌入一样。
但是使用Sel2T转换器,所有的电梯都存在,您可以将Sel计算嵌入到Sel2T中。
https://stackoverflow.com/questions/72490608
复制相似问题