我有以下数据类型:
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)
为什么我的第一个例子不起作用?
每种类型和类型构造函数都有一种.简单的东西就像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看起来它可以正常工作,并且不需要在此上映射函数:您需要以相同的方式同时修改高度,重量和年龄的相同功能吗?
| 归档时间: |
|
| 查看次数: |
607 次 |
| 最近记录: |