【发布时间】:2014-06-12 12:48:28
【问题描述】:
应用函子在 Haskeller 中广为人知并深受喜爱,因为它们能够在有效的上下文中应用函数。
在范畴论方面,可以证明Applicative的方法:
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
相当于拥有Functor f的操作:
unit :: f ()
(**) :: (f a, f b) -> f (a,b)
想法是写pure你只需用给定的值替换unit中的(),写(<*>)你把函数和参数压缩成一个元组,然后映射一个合适的应用程序函数在它上面。
此外,这种对应将Applicative 定律转化为关于unit 和(**) 的自然幺半群定律,所以实际上应用函子正是范畴论者所说的松散单曲面函子(松散是因为@ 987654333@ 只是一个自然变换而不是同构)。
好的,很好,很好。这是众所周知的。但这只是松散的单曲面函子的一个家族——那些尊重乘积的单曲面结构的函子。松散的幺半群函子在源和目标中涉及两种幺半群结构选择:如果将乘积转换为总和,您会得到以下结果:
class PtS f where
unit :: f Void
(**) :: f a -> f b -> f (Either a b)
-- some example instances
instance PtS Maybe where
unit = Nothing
Nothing ** Nothing = Nothing
Just a ** Nothing = Just (Left a)
Nothing ** Just b = Just (Right b)
Just a ** Just b = Just (Left a) -- ick, but it does satisfy the laws
instance PtS [] where
unit = []
xs ** ys = map Left xs ++ map Right ys
unit :: Void -> f Void 是唯一确定的,似乎将 sum 转换为其他幺半群结构变得不那么有趣了,所以你真的有更多的半群在进行。但还是:
- 其他像上述那样的松弛幺半函数是否研究过或有用?
- 有没有像
Applicative这样的简洁替代演示?
【问题讨论】:
-
当你在
PtS.unit的类型中说Void时,你的意思是不是空的,因为它应该是Either的一个单位? -
没关系,您可能打算将
Void表示为空类型。我很困惑,因为类 C 语言中的名称 void 对应于单位类型,您将其写为()。 -
是的,很抱歉造成混乱,但有合理的先例:hackage.haskell.org/package/void
-
Ack,可以说是 C 对 void 的使用是错误的,而不是你的 ;)
标签: haskell functor applicative category-theory alternative-functor