连续性单子变换器是否可以使用 some 和 many 提供一个 Alternative 实例?

14

我们可以将延续单子变换器定义为:

data Cont r m a = Cont {run :: (a -> m r) -> m r}

如果 mAlternative 的成员,我们可以为 Cont r m 提供一个替代实例,方式如下:

Translated text:

如果 mAlternative 的成员,我们可以为 Cont r m 提供一个替代实例,方式如下:

empty = Cont $ \f -> empty
ca <|> cb = Cont $ \f -> run ca f <|> run cb f

然后允许somemany采用它们的默认方法。我的问题是,我们能否根据msomemany的定义来定义somemany,而不是默认定义? 看起来很明显的选项

some ca = Cont $ \f -> some $ run ca f
many ca = Cont $ \f -> many $ run ca f

显然不起作用(它们甚至没有类型检查)。有没有其他方法可以使用它们(如果我们需要m也是单子,那没问题)?

参考:somemany必须是以下方程的最小解:

  • some v =(:)< $ > v <* > many v
  • many v = some v<|> pure []

假设some :: m a -> m [a]many :: m a -> [a]满足此定律,则some :: Cont r m a -> Cont r m [a]many :: Cont r m a -> Cont r m [a]也应满足此定律。

1个回答

4

编号。

这里不存在箭头从

(forall a. f a -> f [a]) ->
(forall r. ((a -> f r) -> f r)) -> (([a] -> f r) -> f r)`

这个函数在一个有趣的方式中利用了它的参数。

forall a. f a -> f [a] 可被应用的唯一场所是 f r。它们是 (a -> f r) -> f r(像你的“明显选项”)和 ([a] -> f r) 的结果。这留下了一个类型为 f [r] 的结果。能够用 forall r. Alternative f => f [r] 所产生的 f [r] 来生成 f r 的唯一方法是,使用一些从自然数到另一个不大于该自然数的数字的偏函数 forall r. [r] -> rf [r] 进行索引。


如果“r”具有一些附加结构,或许还可以做一些事情。例如,也许我们可以“fmap fold”这个“f [r]”,并且通过适当的相容性法则,这可能是等价的。 - luqui
我不太同意。some ca = Cont $ \fla -> run ca $ \a -> (some $ pure a) >>= fla 这个有点有趣。问题是这是否是一个有效的 some 实例。 - PyRulez
你不能仅通过 Alternative f 约束条件从 f [a] 中获取 [a],就像 some $ pure a 一样。你需要 Monad fTraversable f 才能对其进行操作。 - Cirdec
@luqui 是的,这就是为什么我在 forall r 中非常明确的原因。 - Cirdec
我提到过,我对 f 是一个 Monad 感到满意。然而,这篇文章很有用,它表明即使要让它通过类型检查,Monad 也是必需的。 - PyRulez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接