首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >移除反变量函数器的实例声明中的类型同义词

移除反变量函数器的实例声明中的类型同义词
EN

Stack Overflow用户
提问于 2021-01-06 04:12:57
回答 1查看 63关注 0票数 1

如果我定义:

代码语言:javascript
复制
class Contravariant f where
    contramap :: (b -> a) -> f a -> f b

type Op r a = (->) a r

并且想要定义:

代码语言:javascript
复制
instance Contravariant (Op r) where
    contramap f g = g . f

我得到的错误是实例类型不能是同义词。所以我想我需要一些类似的东西:

代码语言:javascript
复制
instance Contravariant ((->) _ r) where
    contramap f g = g . f

这当然不起作用。我怎样才能让Contravariant的这个实例工作?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-06 05:15:03

根据注释,通常的方法是定义一个newtype。注意,语法与定义data类型非常相似,不同之处在于您使用newtype代替data,并且只允许使用一个字段。特别是,您需要一个构造函数,它通常被赋予与类型相同的名称:

代码语言:javascript
复制
newtype Op r a =   Op      (a -> r)
--      ^^         ^^      ^^^^^^^^
--    newtype  constructor  field

这样做的效果是定义了一个与a -> r同构的类型,但类型参数a在完整类型Op r a中“最后”出现,这允许您为Op r定义一个Contravariant实例。请注意,您需要在适当的地方对构造函数进行解包和包装:

代码语言:javascript
复制
instance Contravariant (Op r) where
  contramap f (Op g) = Op (g . f)

要进一步证明这是正确的方法,请注意base中的Data.Functor.Contravariant中的definitions已经这样设置了,除非它们决定使用字段访问器getOp

代码语言:javascript
复制
-- from the Data.Functor.Contravariant source

newtype Op a b = Op { getOp :: b -> a }

instance Contravariant (Op a) where
  contramap f g = Op (getOp g . f)
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65585918

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档