在两个类别之间定义 haskell 中的函子的示例(与加法和乘法幺半群密切相关)
Example of defining a functor in haskell between two categories (which are closely related to additive and multiplicative monoids)
我试图调和函子的数学概念和它的 haskell 概念。
这篇文章http://brianshourd.com/posts/2012-10-26-tilt-functors-in-haskell.html解释了一点,但也许有人可以为以下情况提供一个例子:
假设我定义了以下类别
Add: 其中对象是0,1,2,3,....,态射是(0+), (1+), (2+), ... (0+)是id变形。
Mul: 其中对象是0,1,2,3,....,态射是(0*), (1*), (2*), ... (1*)是id变形。
组成是(.)
如何在 Haskell 中定义这两个类别之间的函子(如果可能并且我上面描述的完全是类别)
谢谢
编辑:根据@chi 的建议,我稍微澄清一下这个问题。我更感兴趣的是你如何将 put/translate 转换为 Haskell 这两个类别之间的任何函子(而不是存在一个函子,例如将任何数字映射到 42 并将任何态射映射到 (1*) 作为@chi sugested)
编辑 2:另一种提问方式是,如何协调这两个语句 "the Functor typeclass, which is basically for things that can be mapped over" 与 "Given categories C and D, a functor F:C→D is a rule that assigns to each object A in C an object F(A) in D. It also assigns to every morphism f:A→B of objects of C a morphism F(f):F(A)→F(B)"。如果类型构造函数 [] (lists) 是一个函子,它连接的两个类别是什么,它是如何映射这两个类别之间的对象和态射的
如果你查看 Haskell 中 class Category
的定义,你会看到这个。
class Category cat where
id :: cat a a
(.) :: cat b c -> cat a b -> cat a c
看,如果类别中的对象是 Int
,那么您需要定义那些函数,其中 a
、b
和 c
是 Int
秒。当集合中的对象是类型而不是值时,这很好。所以你不能让它们成为 Category
.
的实例
也在看fmap
:
fmap :: (a -> b) -> f a -> f b
你可以看到它只对类型有意义(因此属于 Hask 类别)。如果对象是整数,你会传递像 4 --> 5
和 ->
这样的态射只适用于类型。
则(0+)
是Int
到Int
的态射。你需要一个从 2 到 5 的态射。
也许会是这样的:
data IntMorphism = IdMorphism | IntMorphism Int Int
comp :: IntMorphism -> IntMorphism -> IntMorphism
comp IdMorphism m = m
comp m IdMorphism = m
comp (IntMorphism y' z) (IntMorphism x y)
| y /= y' = error "can't compose"
| otherwise = IntMorphism x z
f1 :: Int -> Int
f1 = (+5)
f2 :: IntMorphism -> IntMorphism
f2 IdMorphism = IdMorphism
f2 (IntMorphism x y) = IntMorphism (f1 x) (f1 y)
函子定律成立。特别是:
f2 (comp (IntMorphism y z) (IntMorphism x y))
= f2 (IntMorphism x z)
= IntMorphism (f1 x) (f1 z)
= comp (IntMorphism (f1 y) (f1 z)) (IntMorphism (f1 x) (f1 y))
= comp (f2 (IntMorphism y z)) (f2 (IntMorphism x y))
当然,因为它处理的是值,所以不能使用base中定义的类型类,都是在运行时完成的。
问题在于 Haskell 的 Functor
仅表示某种函子:来自 Haskell 类型和函数类别的函子 (Hask
) 到本身。 Functor
将类型映射到类型(Hask
的对象)并将函数映射到函数(Hask
的态射)。例如,Maybe
Functor
将任何给定类型 a
映射到类型 Maybe a
并使用 fmap
将给定函数 a -> b
映射到函数 Maybe a -> Maybe b
.
在Hask
的范畴中,对象是类型,态射是函数。您的类别将整数作为其对象,因此不符合 Functor
的模式,因此以这种形式提出问题不太有意义,至少对于 Functor
输入 class.
我试图调和函子的数学概念和它的 haskell 概念。 这篇文章http://brianshourd.com/posts/2012-10-26-tilt-functors-in-haskell.html解释了一点,但也许有人可以为以下情况提供一个例子:
假设我定义了以下类别
Add: 其中对象是0,1,2,3,....,态射是(0+), (1+), (2+), ... (0+)是id变形。
Mul: 其中对象是0,1,2,3,....,态射是(0*), (1*), (2*), ... (1*)是id变形。
组成是(.)
如何在 Haskell 中定义这两个类别之间的函子(如果可能并且我上面描述的完全是类别)
谢谢
编辑:根据@chi 的建议,我稍微澄清一下这个问题。我更感兴趣的是你如何将 put/translate 转换为 Haskell 这两个类别之间的任何函子(而不是存在一个函子,例如将任何数字映射到 42 并将任何态射映射到 (1*) 作为@chi sugested)
编辑 2:另一种提问方式是,如何协调这两个语句 "the Functor typeclass, which is basically for things that can be mapped over" 与 "Given categories C and D, a functor F:C→D is a rule that assigns to each object A in C an object F(A) in D. It also assigns to every morphism f:A→B of objects of C a morphism F(f):F(A)→F(B)"。如果类型构造函数 [] (lists) 是一个函子,它连接的两个类别是什么,它是如何映射这两个类别之间的对象和态射的
如果你查看 Haskell 中 class Category
的定义,你会看到这个。
class Category cat where
id :: cat a a
(.) :: cat b c -> cat a b -> cat a c
看,如果类别中的对象是 Int
,那么您需要定义那些函数,其中 a
、b
和 c
是 Int
秒。当集合中的对象是类型而不是值时,这很好。所以你不能让它们成为 Category
.
也在看fmap
:
fmap :: (a -> b) -> f a -> f b
你可以看到它只对类型有意义(因此属于 Hask 类别)。如果对象是整数,你会传递像 4 --> 5
和 ->
这样的态射只适用于类型。
则(0+)
是Int
到Int
的态射。你需要一个从 2 到 5 的态射。
也许会是这样的:
data IntMorphism = IdMorphism | IntMorphism Int Int
comp :: IntMorphism -> IntMorphism -> IntMorphism
comp IdMorphism m = m
comp m IdMorphism = m
comp (IntMorphism y' z) (IntMorphism x y)
| y /= y' = error "can't compose"
| otherwise = IntMorphism x z
f1 :: Int -> Int
f1 = (+5)
f2 :: IntMorphism -> IntMorphism
f2 IdMorphism = IdMorphism
f2 (IntMorphism x y) = IntMorphism (f1 x) (f1 y)
函子定律成立。特别是:
f2 (comp (IntMorphism y z) (IntMorphism x y))
= f2 (IntMorphism x z)
= IntMorphism (f1 x) (f1 z)
= comp (IntMorphism (f1 y) (f1 z)) (IntMorphism (f1 x) (f1 y))
= comp (f2 (IntMorphism y z)) (f2 (IntMorphism x y))
当然,因为它处理的是值,所以不能使用base中定义的类型类,都是在运行时完成的。
问题在于 Haskell 的 Functor
仅表示某种函子:来自 Haskell 类型和函数类别的函子 (Hask
) 到本身。 Functor
将类型映射到类型(Hask
的对象)并将函数映射到函数(Hask
的态射)。例如,Maybe
Functor
将任何给定类型 a
映射到类型 Maybe a
并使用 fmap
将给定函数 a -> b
映射到函数 Maybe a -> Maybe b
.
在Hask
的范畴中,对象是类型,态射是函数。您的类别将整数作为其对象,因此不符合 Functor
的模式,因此以这种形式提出问题不太有意义,至少对于 Functor
输入 class.