`<>` 在这个家族 `<*>,<$>,<&>` 中的含义

meaning of `<>` in this family `<*>,<$>,<&>`

我正在尝试扩展我对 Haskell 中符号的理解:

 $  : Function Application operator (Allow you to apply arguments over a function)
 &  : flipped version of Function Application Operator? (&) = flip ($)
<>  : associative operator (You'll find it in Semigroups and Monoids)
<$> : function application ($) lifted over a Functor structure
<&> : flipped functor map
<*> : applicative operator

<>和这个家庭<*>,<$>,<&>可以link吗?仅查看 <*>,<$>,<&> 时,我很快得出结论,即 <..> 与结构上的某些内容相关,但是结构和关联运算符之间的 link 是什么?

据我所知,<..>没有一般的意思。但是,与其他运算符肯定有一些联系,并且列出的大多数运算符都具有某种助记意义:

  • $是函数应用:f $ x = f x<$> 显然受到 $ 的启发:虽然 f $ xf 应用于 xf <$> xf 应用于 [ 中的每个元素=17=]。 (就个人而言,<$> 是我最喜欢的运算符。)
  • &<&> 之间也存在同样的关系。
  • <> 是幺半群附加运算符:"x" <> "y" <> "z"Sum 1 <> Sum 2 <> Sum 3。 (编辑: 以下可能正确也可能不正确 - 请参阅下面的编辑了解更多详细信息。)据我所知,这些确切的字符只是为了看起来不错而选择的,尽管可能与在数学中使用 来表示一些任意运算符有关。
  • (这只是猜测 - 请参阅下面的编辑以获得更可靠的说明。)我认为选择 <*> 是为了与 <$> 产生很好的共鸣:f <$> x <*> y <*> z.此外,元组也称为产品类型(例如,OCaml 表示像 Int * String 这样的元组类型,对应于 Haskell (Int, String)),因此应用 f $ (x, y, z) 可能会产生共鸣(并不是说有人会这样做而不是普通的 f x y zf (x, y, z)).

编辑: 事实证明@chepner 比我更了解历史 - 感谢您发表评论!在original paper introducing applicative functors中,运算符名称用于应用操作;它是 ASCII 化的 <*>。同一篇论文介绍了<$>。此外 <> 可能 受到 <*> 的启发,因为幺半群和应用被证明是明确相关的。令人惊讶的是,所有的尖括号竟然都相互关联! (尽管非常间接和脆弱...)

这些名称并非来自某些总体概念方案。了解这一点的最佳方式是追踪他们的历史:

  • McBride 和 Paterson 的 Applicative programming with effects uses an asterisk in a circle, ⊛, as the binary operator of Applicative (note that to pick a *-like symbol that suggests a product). When Control.Applicative made it to base(即在 base-2.1/GHC 6.6/2006 年 10 月),变成了 <*>,据我所知,这是最接近的 ASCII 近似值。

  • Control.Applicative 的第一个版本已经包含 <$> 具有效果的应用程序编程 的最终版本我链接到上面还提到了它(有一个细微差别,即 <$> 有一个 Applicative 约束)。选择 $<*> 的混搭作为 fmap 运算符的目的大概是允许我们编写漂亮的应用样式表达式(f <$> u <*> v <*> w),这些表达式可能是可接受的替代品对于那篇论文中提到的成语括号(以 ASCII 呈现,看起来像 [| f u v w |])。

  • Monoid class 在 base 的历史中甚至更早出现(它已经存在于 GHC 5.04。 2、in a Control.Monad.Monoid module); however, there wasn't an infix version of mappend in base until version 4.5 (GHC 7.4, early 2012). Applicative programming with effects also mentions monoids, and suggests a circled plus, ⊕, as a binary operator for mappend. As far as I can tell, the <> name was first suggested by Ross Paterson in a Libraries mailing list thread from 2009, and made its way into a preexisting GHC proposal, and presumably also to Edward Kmett's semigroups package, whose Data.Semigroup module was eventually adopted by base. Paterson chose <> for it being a neutral name, which wouldn't suggest any specific monoid (see also: Why is the mappend infix alias <> instead of +?).