15

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

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

如果是via的成员,我们可以给出Cont r m一个 Alternative 实例mAlternative

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

然后允许somemany采用他们的默认方法。我的问题是,我们可以用's和来定义someand来代替默认定义吗?显而易见的选择manymsomemany

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

显然不起作用(他们甚至不进行类型检查)。有没有其他方法可以使用它们(如果我们m也需要成为一个单子,那很好)?

作为参考,some并且many必须是方程的最小解:

  • 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]

4

1 回答 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). 这留下了 type 的结果f [r]。唯一可以用 aforall r. Alternative f => f [r]来生成 an 的方法是使用从自然数到其他非更大自然数的部分函数对 a 进行f r索引。f [r]forall r. [r] -> r

于 2017-11-28T21:17:16.190 回答