为什么只有 Applicative 需要 `pure` 而 Functor 还不需要?
Why is `pure` only required for Applicative and not already for Functor?
阅读 this Wikibook about Haskell and Category Theory basics,我了解了函子:
A functor is essentially a transformation between categories, so given
categories C and D, a functor F : C -> D
maps any object A in C to F(A), in D.
maps morphisms f : A -> B in C to F(f) : F(A) -> F(B) in D.
...听起来不错。稍后提供示例:
Let's have a sample instance, too:
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap _ Nothing = Nothing
Here's the key part: the type constructor Maybe takes any type T to a
new type, Maybe T. Also, fmap restricted to Maybe types takes a
function a -> b to a function Maybe a -> Maybe b. But that's it! We've
defined two parts, something that takes objects in Hask to objects in
another category (that of Maybe types and functions defined on Maybe
types), and something that takes morphisms in Hask to morphisms in
this category. So Maybe is a functor.
我明白 fmap
的定义是多么关键。我对 "type constructor Maybe" 如何提供第一部分感到困惑。我宁愿期待像 pure
.
这样的东西
如果我做对了,Maybe
而是将 C
映射到 D
。 (因此是类别级别的态射,这可能是 Functor 的要求)
我猜你可以这样改写我的问题:是否有一个没有明显实现 pure
的函子?
我会说 Applicative
实例有点成为 Either
的延伸(如果只为 Bifunctor
提供一个实例我会非常满意,但是在另一方面将它用作 Monad 很方便),并且(恕我直言)不适合这样的事情:
data ABC a = A a | B a | C a
其中 A、B、C 都是 "equally OK"。由于没有明显的选择应该用于 pure
,所以根本不应该提供它。不过 fmap
仍然很好。
Hask 类别将类型作为对象,将函数作为箭头,因此 Functor 实例提供的对象映射必须将类型映射到类型。
fmap
映射箭头,即将函子 f 的函数 a -> b
映射到函数 f a -> f b
。 Functor 类型构造函数是对象的映射,即类型之间的映射。
例如,Maybe
类型构造函数将类型 t
映射到类型 Maybe t
,例如String
到 Maybe String
.
相比之下,pure
将某些基础类型的值映射到相应的应用类型的值,例如"abc" 和 (Just "abc") 分别是 String
和 Maybe String
的值。
If I get it right, Maybe
rather maps C
to D
. (Thus being a morphism on category level, which might be a requirement for a Functor)
不是真的,因为 C
和 D
有类别,而不是 Haskell 类型。 Functor
(即 class 类型的实例,与一般的函子相对)是 Hask 类别( Haskell 类型和函数)到 Hask 本身;也就是说,在这种情况下,C
和 D
都是 Hask。 Wikibook 章节在 Functors on Hask 部分提到了这一点。在您的示例中,Maybe
类型构造函数通过将某种类型 a
(Hask 中的对象)转换为类型 [=20] 来提供映射的第一部分=](Hask中的另一个对象)。
I guess you could rephrase my question like this: Is there a Functor
that does not have an obvious implementation of pure
?
一个例子是 Functor
、(,) a
对。 fmap
很容易写 -- \f (x, y) -> (x, f y)
-- 但 pure
和 (<*>)
需要对 a
的 Monoid
约束,因为没有否则处理额外 a
值的方式。有关更多讨论和其他示例,请参阅 Good examples of Not a Functor/Functor/Applicative/Monad?
我认为您对类型和值感到困惑。下面是函子的定义:
Let C and D be categories. A functor F from C to D is a mapping that:
associates to each object X ∈ C an object F(X) ∈ D.
associates to each morphism f : X → Y ∈ C a morphism F(f) : F(X) → F(Y) ∈ D such that the following conditions hold:
- F(id : X → X) = id : F(X) → F(X) for every object X ∈ C.
- F(g ∘ f) = F(g) ∘ F(f) for all morphisms f : X → Y and g : Y → Z.
一个范畴由对象和对象之间的态射组成。
Haskell 中的所有代码都是 Hask,Haskell 类别的一部分。在 Hask:
- 类型是对象。
- 函数是类型之间的态射。
因此,Haskell 中的所有 Functor
个实例都是从 Hask 到 Hask 的函子(即它们是内函子)。
更严格地说,对于 Haskell 中 Functor
的所有实例:
C = Hask
.
D = Hask
.
现在,每个函子 F 是一个映射,它关联到每个对象 X ∈ C 一个对象 F( X) ∈ D.
- 注意X和F(X)是C和[=的对象44=]D分别.
- 因为C和D都是Hask,所以X 和 F(X) 是类型而不是值。
- 因此,F : Type → Type or in Haskell
f : * -> *
.
的确,这正是 Functor
类型 class 在 Haskell:
中的定义方式
class Functor (f : * -> *) where
fmap :: (x -> y) -> (f x -> f y)
这里,fmap
是函子的第二部分。这是一个从值到值的函数。但是,Functor
本身是一个类型构造函数(即从类型到类型的映射)。这就是 Maybe
是函子而 []
是函子但 Maybe Int
和 [Int]
不是函子的原因。
请注意,pure
不构成仿函数定义的第一部分,因为它是从 X 的实例到 的实例的映射F(X)(即它是从值到值的函数)。但是,我们需要从 X 到 F(X) 的映射(即从类型到类型的映射)。
阅读 this Wikibook about Haskell and Category Theory basics,我了解了函子:
A functor is essentially a transformation between categories, so given categories C and D, a functor F : C -> D
maps any object A in C to F(A), in D.
maps morphisms f : A -> B in C to F(f) : F(A) -> F(B) in D.
...听起来不错。稍后提供示例:
Let's have a sample instance, too:
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap _ Nothing = Nothing
Here's the key part: the type constructor Maybe takes any type T to a new type, Maybe T. Also, fmap restricted to Maybe types takes a function a -> b to a function Maybe a -> Maybe b. But that's it! We've defined two parts, something that takes objects in Hask to objects in another category (that of Maybe types and functions defined on Maybe types), and something that takes morphisms in Hask to morphisms in this category. So Maybe is a functor.
我明白 fmap
的定义是多么关键。我对 "type constructor Maybe" 如何提供第一部分感到困惑。我宁愿期待像 pure
.
如果我做对了,Maybe
而是将 C
映射到 D
。 (因此是类别级别的态射,这可能是 Functor 的要求)
我猜你可以这样改写我的问题:是否有一个没有明显实现 pure
的函子?
我会说 Applicative
实例有点成为 Either
的延伸(如果只为 Bifunctor
提供一个实例我会非常满意,但是在另一方面将它用作 Monad 很方便),并且(恕我直言)不适合这样的事情:
data ABC a = A a | B a | C a
其中 A、B、C 都是 "equally OK"。由于没有明显的选择应该用于 pure
,所以根本不应该提供它。不过 fmap
仍然很好。
Hask 类别将类型作为对象,将函数作为箭头,因此 Functor 实例提供的对象映射必须将类型映射到类型。
fmap
映射箭头,即将函子 f 的函数 a -> b
映射到函数 f a -> f b
。 Functor 类型构造函数是对象的映射,即类型之间的映射。
例如,Maybe
类型构造函数将类型 t
映射到类型 Maybe t
,例如String
到 Maybe String
.
相比之下,pure
将某些基础类型的值映射到相应的应用类型的值,例如"abc" 和 (Just "abc") 分别是 String
和 Maybe String
的值。
If I get it right,
Maybe
rather mapsC
toD
. (Thus being a morphism on category level, which might be a requirement for a Functor)
不是真的,因为 C
和 D
有类别,而不是 Haskell 类型。 Functor
(即 class 类型的实例,与一般的函子相对)是 Hask 类别( Haskell 类型和函数)到 Hask 本身;也就是说,在这种情况下,C
和 D
都是 Hask。 Wikibook 章节在 Functors on Hask 部分提到了这一点。在您的示例中,Maybe
类型构造函数通过将某种类型 a
(Hask 中的对象)转换为类型 [=20] 来提供映射的第一部分=](Hask中的另一个对象)。
I guess you could rephrase my question like this: Is there a
Functor
that does not have an obvious implementation ofpure
?
一个例子是 Functor
、(,) a
对。 fmap
很容易写 -- \f (x, y) -> (x, f y)
-- 但 pure
和 (<*>)
需要对 a
的 Monoid
约束,因为没有否则处理额外 a
值的方式。有关更多讨论和其他示例,请参阅 Good examples of Not a Functor/Functor/Applicative/Monad?
我认为您对类型和值感到困惑。下面是函子的定义:
Let C and D be categories. A functor F from C to D is a mapping that:
associates to each object X ∈ C an object F(X) ∈ D.
associates to each morphism f : X → Y ∈ C a morphism F(f) : F(X) → F(Y) ∈ D such that the following conditions hold:
- F(id : X → X) = id : F(X) → F(X) for every object X ∈ C.
- F(g ∘ f) = F(g) ∘ F(f) for all morphisms f : X → Y and g : Y → Z.
一个范畴由对象和对象之间的态射组成。
Haskell 中的所有代码都是 Hask,Haskell 类别的一部分。在 Hask:
- 类型是对象。
- 函数是类型之间的态射。
因此,Haskell 中的所有 Functor
个实例都是从 Hask 到 Hask 的函子(即它们是内函子)。
更严格地说,对于 Haskell 中 Functor
的所有实例:
C = Hask
.D = Hask
.
现在,每个函子 F 是一个映射,它关联到每个对象 X ∈ C 一个对象 F( X) ∈ D.
- 注意X和F(X)是C和[=的对象44=]D分别.
- 因为C和D都是Hask,所以X 和 F(X) 是类型而不是值。
- 因此,F : Type → Type or in Haskell
f : * -> *
.
的确,这正是 Functor
类型 class 在 Haskell:
class Functor (f : * -> *) where
fmap :: (x -> y) -> (f x -> f y)
这里,fmap
是函子的第二部分。这是一个从值到值的函数。但是,Functor
本身是一个类型构造函数(即从类型到类型的映射)。这就是 Maybe
是函子而 []
是函子但 Maybe Int
和 [Int]
不是函子的原因。
请注意,pure
不构成仿函数定义的第一部分,因为它是从 X 的实例到 的实例的映射F(X)(即它是从值到值的函数)。但是,我们需要从 X 到 F(X) 的映射(即从类型到类型的映射)。