我们可以将延续单子变换器定义为:
data Cont r m a = Cont {run :: (a -> m r) -> m r}
如果 m
是 Alternative
的成员,我们可以为 Cont r m
提供一个替代实例,方式如下:
如果 m
是 Alternative
的成员,我们可以为 Cont r m
提供一个替代实例,方式如下:
empty = Cont $ \f -> empty
ca <|> cb = Cont $ \f -> run ca f <|> run cb f
然后允许some
和many
采用它们的默认方法。我的问题是,我们能否根据m
的some
和many
的定义来定义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]
也应满足此定律。
some ca = Cont $ \fla -> run ca $ \a -> (some $ pure a) >>= fla
这个有点有趣。问题是这是否是一个有效的some
实例。 - PyRulezAlternative f
约束条件从f [a]
中获取[a]
,就像some $ pure a
一样。你需要Monad f
或Traversable f
才能对其进行操作。 - Cirdecforall r
中非常明确的原因。 - Cirdecf
是一个Monad
感到满意。然而,这篇文章很有用,它表明即使要让它通过类型检查,Monad
也是必需的。 - PyRulez