Id
的某些实例也是Category
的实例。例如:
Functor
{-# LANGUAGE ExistentialQuantification, TupleSections #-}
import Prelude hiding (id, (.))
import Control.Category
import Control.Arrow
data State a b = forall s. State (s -> a -> (s, b)) s
apply :: State a b -> a -> b
apply (State f s) = snd . f s
assoc :: (a, (b, c)) -> ((a, b), c)
assoc (a, (b, c)) = ((a, b), c)
instance Category State where
id = State (,) ()
State g t . State f s = State (\(s, t) -> assoc . fmap (g t) . f s) (s, t)
(.:) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
(.:) = fmap . fmap
instance Functor (State a) where
fmap g (State f s) = State (fmap g .: f) s
instance Arrow State where
arr f = fmap f id
first (State f s) = State (\s (x, y) -> fmap (,y) (f s x)) s
arr f = fmap f id
。是instance Arrow State
的所有实例都是如此,这些实例也是Category
的实例吗?类型签名是:
Functor
在我看来,它们应该是等价的。
答案 0 :(得分:6)
首先让我们清楚Arrow C
的含义。嗯,这是两个完全不同的东西 - 在我的书中,
arr
来自后者。 “概括” Hask ?这意味着只需要从 Hask 类别到C
的映射。 - 从数学上讲,从一个类别到另一个类别的映射正是functor的作用! (标准的Functor
类实际上只涵盖了一种非常特殊的函子,即 Hask 上的endofunctors。)arr
是非endofunctor的态射方面,即“canonical embedding functor” Hask →C
。
从这个角度来看,前两个箭头法则
arr id = id
arr (f >>> g) = arr f >>> arr g
只是仿函数法。
现在,如果您为某个类别实施Functor
实例,这意味着什么?为什么,我敢说它只是意味着你表达了同样的规范嵌入仿函数,而是通过 Hask 中的C
的必要表示(这使得它成为整体的endofunctor)。因此,我认为是的,\f -> fmap f id
应该等同于arr
,因为基本上它们是两种表达同一事物的方式。
答案 1 :(得分:3)
这是一个补充左撇子解释的推导。为清楚起见,我将为(.)
保留id
和(->)
,并为常规(<<<)
方法使用id'
和Category
。
我们从preComp
开始,也称为(>>>)
:
preComp :: Category y => y a b -> (y b c -> y a c)
preComp v = \u -> u <<< v
fmap
在 Hask endofunctors之间进行自然转换。对于Category
实例Functor
,preComp v
是自然转换(从y b
到y a
),因此它与{{1}通勤}}。由此得出:
fmap
那是我们的候选人fmap f . preComp v = preComp v . fmap f
fmap f (u <<< v) = fmap f u <<< v
fmap f (id' <<< v) = fmap f id' <<< v
fmap f v = fmap f id' <<< v
!因此,让我们定义arr
。我们现在可以验证arr' f = fmap f id'
遵循第一个箭头法......
arr'
......第二个也是:
-- arr id = id'
arr' id
fmap id id'
id'
我想这是我们能得到的。其他五个箭头法则涉及-- arr (g . f) = arr g <<< arr f
arr' (g . f)
fmap (g . f) id'
(fmap g . fmap f) id'
fmap g (fmap f id')
fmap g (arr' f)
fmap g id' <<< arr' f -- Using the earlier result.
arr' g <<< arr' f
,左下角指出first
和arr
是独立的。