繁体   English   中英

为什么我不能用 arr 和 *** / &&& 定义 Haskell Arrow 实例

[英]Why can't I define a Haskell Arrow instance in terms of arr and *** / &&&

我仍在掌握在 Haskell 中定义和使用箭头的方法。 在定义新箭头时,我更容易考虑 *** 或 &&& 而不是第一个和第二个,因为大多数时候我希望对两个箭头组合时进行特殊处理。

然而,箭头 class 不允许根据 arr 和 *** 或 &&& 定义箭头,并且需要包含 first 的定义。 这意味着我被迫编写如下代码 -

instance Arrow X where
  arr f = ...
  f (***) g = ...
  first f = f *** arr id

在我看来,在 Control.Arrow 模块中包含“first”的默认定义并没有什么害处。 这将允许我们在定义 first 或 *** 之间进行选择。

箭头 class 中没有包含 first 的默认定义是否有充分的理由? 我能想到的唯一原因是用户可能会忽略 first 和 *** 的定义,然后你会有循环定义,但这是唯一的原因吗?

Data.Monoid 有一个类似的缺失替代最小完整定义:mconcat。 与 Arrow 一样,出于性能原因,它缺少这种替代方案。 由于 mconcat 中的模式匹配, mappend ab = mconcat[a,b]效率低下。

使用 Arrows,效率不那么明显但更加残酷:想想无法优化arr id吧:

使用 CleisliArrow 作为示例箭头,它是这样的:

first f (x,y) = do
    x' <- f x
    return (x',y)

它会是:

first f (x,y) = do
    x' <- f x
    y' <- arr id y
    return (x',y')

arr function 无法与 id function 进行模式匹配,因此必须引入额外的开销来包装 function。

我实际上相信这是阻止某人编写默认方法的循环。 但正如@camccann 指出的那样,这应该阻止任何人。 建议改变!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM