我们可以将延续单子变换器定义为
data Cont r m a = Cont {run :: (a -> m r) -> m r}
如果是via的成员,我们可以给出Cont r m
一个 Alternative 实例m
Alternative
empty = Cont $ \f -> empty
ca <|> cb = Cont $ \f -> run ca f <|> run cb f
然后允许some
并many
采用他们的默认方法。我的问题是,我们可以用's和来定义some
and来代替默认定义吗?显而易见的选择many
m
some
many
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]
。