这是另一个Haskell-through-category-theory问题.
让我们以简单而着名的方式为例.fmap
?所以fmap :: (a -> b) -> f a -> f b
,省略实际上f
是一个事实Functor
.据我了解,(a -> b) -> f a -> f b
不过是一个语法糖的(a -> b) -> (f a -> f b)
; 结论:
(1) fmap
是产生功能的功能.
现在,Hask也包含函数,因此(a -> b)
,特别(f a -> f b)
是Hask的一个对象(因为Hask的对象是明确定义的Haskell类型 - a-ka数学集 - 并且确实存在(a -> b)
每种可能的类型集a
,对?).所以,再一次:
(2) (a -> b)
是Hask的一个对象.
现在奇怪的事情发生了:fmap
显然,它是Hask 的态射,因此它是一个函数,它接受另一个函数并将其转换为另一个函数; 最终功能尚未应用.
因此,我们需要一个更Hask的射从获取(f a -> f b)
到f b
.对于每个i
类型的项目,a
存在一个apply_i :: (f a -> f b) -> f b
定义为的态射\f -> f (lift i)
,其中lift i
是一种f a
用特定i
内部构建的方法.
另一种看待它的方式是GHC
:(a -> b) -> f a -> f b
.与我上面所写的相反,(a -> b) -> f a
是映射到Hask的常规对象.但是这种观点与Haskell的基本公理相矛盾 - 没有多元函数,而是应用(curried)替代方案.
我想在这一点上问:(a -> b) -> f a -> f b
假设是一个(a -> b) -> (f a -> f b) -> f b
,为了简单而加糖,还是我错过了一些真正非常重要的东西?
被
(a -> b) -> f a -> f b
假设是一个(a -> b) -> (f a -> f b) -> f b
,加糖为了简化
不,我认为你所缺少的,并不是你的错,只是一个非常特殊的情况,中间箭头可以被称为态射,就像外壳一样.Functor类的一般情况是(伪语法)(a -> b) -> (f a -> f b)
(a -> b) -> (f a -> f b)
class (Category (??>), Category (~>)) => Functor f (??>) (~>) where fmap :: (a ??> b) -> f a ~> f b
因此,它将类别中的态射映射到类别中的??>
态射中的态射~>
,但这种态射映射本身只是一个功能.你的权利,在Hask中,特别是函数箭头与态射箭头是同一种箭头,但从数学上讲,这是一个相当简洁的场景.