Haskell中如何不使用newtype重排实例定义的类型参数?
映射
T类型的第一个参数a是否可行? 结论:不行,没办法在不修改T类型定义、不使用newtype重排参数的前提下,为映射a的逻辑实现标准的Functor实例。
原因
Haskell的Functor类要求实例必须是一个接受单个类型参数的构造器(即* -> * kind)。对于T a b来说,它的kind是* -> * -> *,要成为Functor实例,必须固定其中一个参数,让它变成* -> *的构造器:
- 固定第一个参数
a,得到T a :: * -> *,这就是我们能实现映射b的Functor实例的原因; - 但如果要映射
a,需要固定第二个参数b,得到T _ b :: * -> *,而Haskell的类型构造器是左柯里化的,没办法直接通过部分应用得到这个形式——标准Functor只支持对最右侧的类型参数进行映射。
替代方案
虽然没法做Functor实例,但可以自己定义一个专门映射a的函数:
mapA :: (a -> a') -> T a b -> T a' b mapA f (T a b) = T (f a) b
这个函数完全能实现对a的映射需求,只是不属于Functor类的范畴。
内容的提问来源于stack exchange,提问作者Atpur Rafif
相关产品推荐
相关产品推荐

