有多种类型的Functor声明?

Bab*_*ham 0 haskell functor

我有以下数据类型:

data Users id height weight = User id height weight

instance Functor Users where
fmap f (User id height weight) = User(f id height weight)
Run Code Online (Sandbox Code Playgroud)

然而这不会编译?

当我使用具有单个参数的类型时,它工作正常,例如:

data Users id = User id
instance Functor Users where
fmap f (User id) = User (f id)
Run Code Online (Sandbox Code Playgroud)

为什么我的第一个例子不起作用?

che*_*ner 5

每种类型和类型构造函数都有一种.简单的东西就像Int是善良的*.你的单参数类型构造函数Users有种类* -> *; 它需要一种类型并返回一个新类型.你的第一个例子是Users善良的* -> * -> * -> *; 它需要三种类型并返回一个新类型.

Functor仅适用于类型构造函数* -> *.这允许您Functor为第二个Users类型构造函数定义实例,但不能为第一个构造函数定义实例.

想想你的第一次尝试:数据构造函数Users有三个参数,但你定义fmap只用一个调用它的尝试,f的返回值.Users只要您愿意将所有三个字段设为相同类型,您就可以创建一个仿函数:

data Users a = Users a a a

instance Functor Users where
    fmap f (Users a b c) = Users (f a) (f b) (f c)
Run Code Online (Sandbox Code Playgroud)

理论上,您可以定义一个类Trifunctor(有一个Bifunctor类可用):

class Trifunctor f where
    trimap :: (a1 -> b1) -> (a2 -> b2) -> (a3 -> b3) -> f a1 a2 a3 -> f b1 b2 b3

data Users a b c = Users a b c

instance Trifunctor Users where
    trimap f g h (Users a b c) = Users (f a) (g b) (h c)
Run Code Online (Sandbox Code Playgroud)

但这是多么有用的问题值得商榷.Functor对于通用容器是有用的,因为它们具有广泛的用途.Users另一方面,看起来非常具体.您通常不需要您定义的灵活性; data User = User Int Int Int看起来它可以正常工作,并且不需要在此上映射函数:您需要以相同的方式同时修改高度,重量和年龄的相同功能吗?