我最近写了
do
e <- (Left <$> m) <|> (Right <$> n)
more actions
case e of
Left x -> ...
Right y -> ...
这似乎很尴尬。我知道protolude
(以及其他一些包)定义了
-- Called eitherP in parser combinator libraries
eitherA :: Alternative f => f a -> f b -> f (Either a b)
但即便如此,这一切都感觉有点手动。有什么我没见过的收紧它的好模式吗?
你或许可以这样做:
do
let acts = do more actions
(do x <- m; acts; ...) <|> (do y <- n; acts; ...)
我不知道这对你来说是否更好。
(当然,如果这些更多操作
绑定了许多变量,那么这就不会很好地解决问题)
这是对这个问题的过度思考,但是。。。
在您的代码中,或
的每个分支的类型可能是不同的,但它们不会逃出do块,因为它们被左
和右
的延续“擦除”。
这看起来有点像存在主义。也许我们可以声明一个新类型,它将初始操作与其延续一起打包,并为该新类型提供一个可选的
实例。
实际上,我们不必声明它,因为这样一个新类型已经存在于Hackage中:它是kan-扩展中的Coyoneda。
data Coyoneda f a where
Coyoneda :: (b -> a) -> f b -> Coyoneda f a
Alternative f => Alternative (Coyoneda f)
MonadPlus f => MonadPlus (Coyoneda f)
在我们的例子中,“返回值”本身将是一个一元动作
m
,因此我们想要处理Coyoneda m(ma)
类型的值,其中ma
是整个do块的类型。
了解所有这些,我们可以定义以下函数:
sandwich :: (Foldable f, MonadPlus m, Monad m)
=> m x
-> f (Coyoneda m (m a))
-> m a
sandwich more = join . lowerCoyoneda . hoistCoyoneda (<* more) . asum
重新实现原始示例:
sandwich more [Coyoneda m xCont, Coyoneda n yCont]
我只是注意到OP在评论中表达了同样的想法。不管怎样,我还是要发表我的想法。
Coyoneda是一个巧妙的技巧,但对于这个特殊的问题,它有点矫枉过正。我想你所需要的只是常规的旧的延续。
让我们命名这些...
s:
do
e <- (Left <$> m) <|> (Right <$> n)
more actions
case e of
Left x -> fx x
Right y -> fy y
那么,我们可以这样写:
do
e <- (fx <$> m) <|> (fy <$> n)
more actions
e
这有点微妙——使用很重要
我试图在R中合并2个数据帧,但我有两个不同的列,带有不同类型的ID变量。有时一行会有其中一列的值,而另一列却没有。我想同时考虑它们,这样,如果一个帧缺少一个列的值,那么将使用另一个列。 我想合并这两个数据帧,得到2行: null 编辑:理想情况下,输出如下所示: 第1行匹配,因为列“first”在两个数据帧中具有相同的值,并且它填充了来自DF2的“second”的值 第2行匹配,因为列“secon
问题内容: 您好,我想基于数组中的唯一项合并数组。 我拥有的对象 在这个totalCells数组中,我有几个这样的对象 现在,我想制作一个数组,在该数组中我可以基于lineNumber进行数组组合。 就像我有一个具有lineNumber属性和cellWidth集合的对象。我可以这样做吗? 我可以遍历每一行并检查行号是否相同,然后按该单元格宽度。有什么办法我可以算吗? 我正在尝试获得这样的输出。 问
问题内容: 我有一个带有4列的(example-)数据框: 我现在想将B,C和D列合并/合并到新的E列,如本例所示: 我在这里发现了一个非常类似的问题,但这在A列的末尾添加了合并的列B,C和D: 感谢帮助。 问题答案: 选项1 使用和 选项2 使用分配和 选项3 最近,我喜欢第3个选项。 使用
问题内容: 我有两个数组。 我需要合并这些数组,并在下拉列表中显示为 我怎么能使用swift.im新手来快速获得此结果,有人可以帮忙吗? 问题答案: 压缩数组并连接结果:
问题内容: 考虑下表, 我如何获得以下结果 尝试过的形式但未获得正确的结果,数学将始终放在Subject_1之下,而Science总是在SUbject_2之下。 问题答案: 使用: 最大限度 通过…分组 SQL>选择名称, 2个最大(subject_1)subject_1, 3个最大(marks_1)个marks_1, 4个MAX(subject_2)subject_2, 5个最大(marks_2
问题内容: 我有一个表的数组列类型: 我想写一个查询,每个标题生成一个数组(理想情况下,它将是一个设置/去重复的数组) 例如 上面的查询当然行不通,但是我想产生2行: 任何帮助或指针将不胜感激(我使用的是Postgres 9.1) 基于Craig的帮助,我得出以下结论(语法略有更改,因为9.1完全按照他的显示抱怨该查询) 问题答案: 自定义汇总 方法1:定义自定义集合。这是我之前写的。 横向查询