{<*>)中的*是否具有特殊含义?

时间:2019-04-04 10:11:12

标签: haskell operators naming-conventions applicative category-theory

试图加深我对Haskell中符号的理解:

  • ($):函数应用运算符(允许您对函数应用自变量)
  • (&):功能应用程序运算符的翻转版本? (&) = flip ($)
  • (<>):关联运算符(您可以在半群和Monoid中找到它)
  • (<$>):函数应用程序($)放在Functor结构上
  • (<&>):翻转的函子图

我们可以在(*)(<*>)之间建立链接吗?

我实际上不理解*的含义...

1 个答案:

答案 0 :(得分:17)

这是故意的。 <*>具有tensor product的特征。最好在列表monad中看到:

Prelude> (,) <$> ['a'..'e'] <*> [0..4]
[('a',0),('a',1),('a',2),('a',3),('a',4)
,('b',0),('b',1),('b',2),('b',3),('b',4)
,('c',0),('c',1),('c',2),('c',3),('c',4)
,('d',0),('d',1),('d',2),('d',3),('d',4)
,('e',0),('e',1),('e',2),('e',3),('e',4)]

更一般地,应用函子(aka monoidal functors)从函子后面的两个对象(即产品类型,也称为元组或通过使用curring 两个函数参数)的乘积映射到函子-函子之前的产品结果。因此,这确实是一个相当不错的产品操作。

φ A B FA FB < / em>→ F A B

...在Haskell中,

φ :: (f a, f b) -> f (a,b)
φ = uncurry (liftA2 (,))
-- recall `liftA2 f x y = f <$> x <*> y`

甚至

{-# LANGUAGE TypeOperators #-}
type x ⊗ y = (x,y)

φ :: f a ⊗ f b -> f (a⊗b)

要了解历史的一面,请查看McBride and Paterson 2008(doi:10.1017/S0956796807006326),这是第一个介绍Applicative类型类的论文。他们注意到

  

Applicative类具有非对称操作,但有一个等效的对称定义。

class Functor f -> Monoidal f where
    unit :: f ()
    (★) :: f a -> f b -> f (a,b)

     

对于任何应用函子,这些操作显然是可定义的...

因此,<*>是McBride和Paterson的运算符的ASCII形式,反过来又是的“应用”形式,类别理论家将其称为非简化形式,