5

与haskell中的常规函数​​相比,箭头有什么优势。他们能做什么功能不能。函数可以使用 fmap 映射结构。

4

2 回答 2

6

从更广泛的角度来看,箭头会让你脱离Hask并进入其他有待探索的类别。Kleisli 类别可能是 Haskeller 最熟悉的类别,其次是Cokleisli。这些是Hask的自然“扩展” :在结果或参数周围添加一个 endofunctor,然后如果

  • Kleisli:函子是一个单子,所以id ≅ return :: a -> m a

    (.) ≅ (<=<) :: (b->m c) -> (a->m b) -> a->m c
    
  • CoKleisli: 函子是一个共单子,所以id ≅ coreturn :: m a -> a

    (.)     ::     (m b->c) -> (m a->b) -> m a->c
    

(为此,您还不需要Arrow,只有Category。但是一般类别不是很有趣,您通常需要幺半群甚至笛卡尔封闭类别,这就是Arrow大致目标。)

但肯定还有很多其他类别大多数与Hask没有太大关系,也不能用标准Arrow类来表达,主要是因为对象具有并非每个 Haskell 类型都满足的特殊属性。实际上,如果您添加约束对象类型的能力,可能性会立即变得更广泛。但是,即使您使用标准类,甚至可能只是简单地在 中->,带有箭头的自然无点组合样式通常会非常漂亮、简洁,并开辟了思考转换的新方法。

于 2014-04-16T00:39:39.563 回答
3

函数只是箭头的一个实例,就像在问“为什么使用 monad 而不是仅仅Maybe”。

你可以用箭头做的任何事情当然可以用函数来完成,因为Arrow (->)实例只能谈论一小部分函数,​​即Arrow类型类中的内容。但是,arrows 的实例不仅仅是普通函数,因此我们可以使用 ssame 函数来操作更复杂的类型。

箭头很好,因为它们可以具有比函数更多的结构,当使用 just 遍历时fmap,我们无法累积效果,比 monad 更具表现力!考虑 Kleisli 箭头,

newtype Kleisli m a b = Kleisli {runKleisli :: a -> m b}

m是一个单子时,这会形成一个箭头。所以每个都Monad形成一个箭头,因此我们可以通过无缝组合 's 来建立单子计算,a -> m b并做各种类似的有用的事情。一些 XML 库使用箭头来抽象从元素到其子元素的函数,并使用它来遍历文档。其他解析器使用箭头(它们最初的目的),尽管现在这似乎不再受Applicative.

您希望注意到的一点是箭头更通用,当我们只谈论箭头时,我们避免复制我们需要编写的所有代码来使用我们的解析器、xml 抓取器和 monadic 函数!

这就像选择Monadover一样Maybe,我们失去了一些权力,因为我们不再能够做出特定的陈述,但我们得到了更通用的代码作为回报。

于 2014-04-15T23:45:49.400 回答