class Functor的声明中,类型变量可以是函数类型吗?

In the declaration of class Functor, can the type variables be function types?

在Haskell中,classFunctor声明为:

class   Functor f   where
fmap    ::  (a  ->  b)  ->  f   a   ->  f   b

类型变量 ab 可以是函数类型,还是必须是非函数类型?

如果它们可以是函数类型,那么 class Functor 是否实际上与 class Applicative 相同,使得 [=19] =] 能够应用于具有任意数量参数的函数?根据 Hutton 在 Haskell 中的 Programming 所说:

Functors abstract the idea of fmap mapping a function over each element of a structure. Applicatives generalize this idea to allow fmap mapping functions with any number of arguments to be mapped, rather than being restricted to functions with a single argument.

在应用中:

fmap0 ::  a   ->  f   a
fmap0 =   pure
fmap1 ::  (a  ->  b)  ->  f   a   ->  f   b
fmap1 g   x   =   pure    g   <*> x
fmap2 ::  (a  ->  b   ->  c)  ->  f   a   ->  f   b   ->  f   c
fmap2 g   x   y   =   pure    g   <*> x   <*> y
fmap3 ::  (a  ->  b   ->  c   ->  d)  ->  f   a   ->  f   b   ->  f   c   ->  f   d
fmap3 g   x   y   z   =   pure    g   <*> x   <*> y   <*> z

Class Applicative 声明为:

class Functor f   =>  Applicative f   where
pure  ::  a   ->  f   a
(<*>) ::  f   (a  ->  b)  ->  f   a   ->  f   b

谢谢。

Can type variables a and b be function types, or must they be non-function types?

ab 可以是 任何 类型,所以函数类型也是如此。

例如我们可以使用:

fmap <b>(+)</b> [1,4,2,5]

这里 (+) 有类型:

fmap :: Functor f => (a -> b       ) -> f a -> f b
(+)  :: Num c =>      c -> (c -> c)

所以这里 b ~ c -> c,因此 b 是一个函数。

a 是一个函数的例子是:

fmap <b>($ 2)</b> [ (1+), (2*), (3-) ]

这里我们有类型:

fmap :: Functor f => (a        -> b) -> f a -> f b
($ 3)  :: Num c =>    (c -> d) -> d

所以 a ~ (c -> d) 这里,我们因此将 3 应用到列表中的所有函数。

请注意,我们没有在此处添加额外的 fmap 定义(如 fmap<sub>1</sub> fmap<sub>2</sub>, ...)。只是 a 可以替换为类型 c -> d,等等)。

If they can be function types, isn't it that class Functor become effectively the same as class Applicative.

不,因为例如没有说 pure 可以针对给定的 Functor 实施。假设您创建了一个数据类型:

type Owner = String

data Owned a = Owned Owner a

那么Owned可以实现为Functor的一个实例:

instance Functor Owned where
    fmap f (Owned o x) = Owned o (f x)

但是实现 pure :: a -> Owned a 是不可能的:为什么要成为对象的所有者?

Can type variables a and b be function types

– 是的,当然。

isn't it that class Functor become effectively the same as class Applicative

不,绝对不是。如果你在 fmap 签名的 ab 中插入一个函数类型,你会得到像

这样的东西
fmap :: ((x -> y) -> b) -> f (x -> y) -> f b

fmap :: (a -> p -> q) -> f a -> f (p -> q)

但至关重要的是,fmap 总是恰好取一个 f _ wrapped-value 并吐出恰好一个这样的值。 Applicative 同时允许您接受 任意数量 的包装值,前提是您给它一个函数来处理包含的值。

ab 可以是函数类型。它们可以是任何类型。事实上,一个有效的 Functor 必须 允许它们是任何类型。

为了回答您的 Applicative 问题,让我们试一试。

fmap :: (a -> b -> c) -> f a -> f (b -> c)

好的,太棒了!现在我可以将 f a 转换为 f (b -> c)。但是……然后呢?我不能将 f (b -> c) 应用于一个论点。这不是一个功能;这是我的仿函数类型的值。要是我们有一个带有这个签名的函数就好了……

superFmap :: f (b -> c) -> f b -> f c

但这确实很像

(<*>) :: f (b -> c) -> f b -> f c

Applicative 的成员。因此,我们需要 Applicative 才能应用此次要结果。

其他答案说的是正确的。出于类似的原因,我们也无法实现 pure。但重要的是要注意,我们甚至不能在一般情况下得到 (<*>),因为如果我们可以那么那将意味着每个 Functor 都是 Apply,当然也不是这种情况。