双函子与箭头方法
Bifunctor vs. Arrow methods
Bifunctor
和 Arrow
方法之间有一点重叠:
class Bifunctor p where
first :: (a -> a') -> p a b -> p a' b
second :: (b -> b') -> p a b -> p a b'
bimap :: (a -> a') -> (b -> b') -> p a b -> p a' b'
class Arrow (~~>) where
...
first :: (a ~~> a') -> (a, b) ~~> (a', b)
second :: (b ~~> b') -> (a, b) ~~> (a, b')
(***) :: (a ~~> a') -> (b ~~> b') -> (a, b) ~~> (a', b')
Bifunctor
class 的规律与 Functor
完全相似。
Arrow
class 有许多不同的法律和一个关于 (***)
的有点神秘的警告: "Note that this is in general not a functor." 令人惊讶的是(对我来说)只有一个法律关于 (***)
:
first f >>> arr (id *** g) = arr (id *** g) >>> first f
Arrow (->)
实例和 Bifunctor (,)
实例完全匹配,因此 bimap @(,) = (***) @(->)
。这有什么特别的意义吗?有没有有意义的假设
class Foo (~~>) p where
biFoo :: (a ~~> a') -> (b ~~> b') -> p a b ~~> p a' b'
如果是这样,是否承认函数依赖性?
Arrow
是 cartesian closed categories, or a least cartesian monoidal categories 的 class 的(有点混蛋)前身。具体来说,对于张量积为(,)
且单位元为()
.
的幺半群范畴
回想一下 monoidal category 的特征在于张量积是双函子,因此 Arrow
和 Bifunctor
之间存在联系。
***
实际上有比您列出的更多的法律,只是图书馆选择根据 first
来制定这些法律。这是 class:
的等效定义
class (Category k, Category k') => EnhancedCategory k k' where
arr :: k a b -> k' a b
-- arr id ≡ id
-- arr (f . g) = arr f . arr g
class (EnhancedCategory (->) a) => Arrow a where
(***) :: a b c -> a b' c' -> a (b,b') (c,c')
-- (f***id) . (g***id) ≡ (f.g)***id
-- (id***f) . (id***g) ≡ id***(f.g)
-- arr fst . (f***id) ≡ f . arr fst
-- arr snd . (id***g) ≡ g . arr snd
-- ¿ arr swap . (f***g) ≡ (g***f) . arr swap ?
-- ((f***g)***h) . assoc ≡ assoc . (f***(g***h))
diag :: a b (b,b)
first :: Arrow a => a b c -> a (b,d) (c,d)
first f = f***id
second :: Arrow a => a b c -> a (d,b) (d,c)
second g = id***g
(&&&) :: Arrow a => a b c -> a b d -> a b (c,d)
f&&&g = (f***g) . diag
顺便说一句,也可以删除提升纯函数的arr
,而只给超级class专用方法fst
、snd
和assoc
。 I call that class Cartesian
. This allows defining “arrow” categories that don't contain arbitrary Haskell functions; linear maps 是一个重要的例子。
您可以选择a different notion of strength to get a different kind of Arrow
。
class Category a => ArrowChoice a where
arr :: (b -> c) -> a b c
(+++) :: a b c -> a b' c' -> a (Either b b') (Either c c')
换句话说,您的笛卡尔闭范畴的张量积不需要正好 (,)
。你能想出的任何张量积都有一个相应的强度概念,每个强度都会给你相应的变化 Arrow
.
值得注意的是,许多 profunctor 都是 Strong
和 Choice
,因此您的 Foo
(基本上是对张量积 p
的概括 Strong
) '具有功能依赖性。
不幸的是,base
中的 Control.Arrow
模块将层次结构混淆了一点(例如,他们的 ArrowChoice
有 Arrow
作为超类)。
Bifunctor
和 Arrow
方法之间有一点重叠:
class Bifunctor p where
first :: (a -> a') -> p a b -> p a' b
second :: (b -> b') -> p a b -> p a b'
bimap :: (a -> a') -> (b -> b') -> p a b -> p a' b'
class Arrow (~~>) where
...
first :: (a ~~> a') -> (a, b) ~~> (a', b)
second :: (b ~~> b') -> (a, b) ~~> (a, b')
(***) :: (a ~~> a') -> (b ~~> b') -> (a, b) ~~> (a', b')
Bifunctor
class 的规律与 Functor
完全相似。
Arrow
class 有许多不同的法律和一个关于 (***)
的有点神秘的警告: "Note that this is in general not a functor." 令人惊讶的是(对我来说)只有一个法律关于 (***)
:
first f >>> arr (id *** g) = arr (id *** g) >>> first f
Arrow (->)
实例和 Bifunctor (,)
实例完全匹配,因此 bimap @(,) = (***) @(->)
。这有什么特别的意义吗?有没有有意义的假设
class Foo (~~>) p where
biFoo :: (a ~~> a') -> (b ~~> b') -> p a b ~~> p a' b'
如果是这样,是否承认函数依赖性?
Arrow
是 cartesian closed categories, or a least cartesian monoidal categories 的 class 的(有点混蛋)前身。具体来说,对于张量积为(,)
且单位元为()
.
回想一下 monoidal category 的特征在于张量积是双函子,因此 Arrow
和 Bifunctor
之间存在联系。
***
实际上有比您列出的更多的法律,只是图书馆选择根据 first
来制定这些法律。这是 class:
class (Category k, Category k') => EnhancedCategory k k' where
arr :: k a b -> k' a b
-- arr id ≡ id
-- arr (f . g) = arr f . arr g
class (EnhancedCategory (->) a) => Arrow a where
(***) :: a b c -> a b' c' -> a (b,b') (c,c')
-- (f***id) . (g***id) ≡ (f.g)***id
-- (id***f) . (id***g) ≡ id***(f.g)
-- arr fst . (f***id) ≡ f . arr fst
-- arr snd . (id***g) ≡ g . arr snd
-- ¿ arr swap . (f***g) ≡ (g***f) . arr swap ?
-- ((f***g)***h) . assoc ≡ assoc . (f***(g***h))
diag :: a b (b,b)
first :: Arrow a => a b c -> a (b,d) (c,d)
first f = f***id
second :: Arrow a => a b c -> a (d,b) (d,c)
second g = id***g
(&&&) :: Arrow a => a b c -> a b d -> a b (c,d)
f&&&g = (f***g) . diag
顺便说一句,也可以删除提升纯函数的arr
,而只给超级class专用方法fst
、snd
和assoc
。 I call that class Cartesian
. This allows defining “arrow” categories that don't contain arbitrary Haskell functions; linear maps 是一个重要的例子。
您可以选择a different notion of strength to get a different kind of Arrow
。
class Category a => ArrowChoice a where
arr :: (b -> c) -> a b c
(+++) :: a b c -> a b' c' -> a (Either b b') (Either c c')
换句话说,您的笛卡尔闭范畴的张量积不需要正好 (,)
。你能想出的任何张量积都有一个相应的强度概念,每个强度都会给你相应的变化 Arrow
.
值得注意的是,许多 profunctor 都是 Strong
和 Choice
,因此您的 Foo
(基本上是对张量积 p
的概括 Strong
) '具有功能依赖性。
不幸的是,base
中的 Control.Arrow
模块将层次结构混淆了一点(例如,他们的 ArrowChoice
有 Arrow
作为超类)。