跨类型构造函数编写泛型仿函数实例? [英] Writing a generic functor instance across type constructors?

查看:90
本文介绍了跨类型构造函数编写泛型仿函数实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习基本类型类,并为我的类型Test a写了自己的functor实现(与Maybe一样):

I'm learning basic type classes and have written my own implementation of functor for my type Test a (behaves just like Maybe):

data Test a = Test a | Emp

class FC c a where
  t :: (a -> b) -> c a -> c b

instance FC Test a where
  t f (Test a) = Test (f a) 
  t f (Emp) = Emp

instance FC Maybe a where
  t f (Just a) = Just (f a) 
  t f (Nothing) = Nothing

是否可以实现类似的内容:

Is it possible to implement something like:

instance FC c where
  t f (c v) = c (f v)

错误:

Parse error in pattern: c

换句话说,将类型构造函数抽象出来,替换为cv,从而创建一个通用实例,该实例可以应用于具有上下文的任何值吗?

In other words, abstract away the type constructor, replace with c and v, therefore creating a general instance that can be applied to any value with a context?

推荐答案

如您所知,c a并不是语法上有效的模式.但是,请阅读您的问题作为功能建议:这将如何工作?并非每个Functor都有一个单元素构造函数,可以根据您的模式进行映射.一些例子:

As you've learned, c a is not a syntactically valid pattern. But reading your question instead as a feature proposal: How would that work? Not every Functor has a single-element constructor which can be mapped over according to your pattern. Some examples:

data Pair a = Pair a a  -- more than one element
instance Functor Pair where
    fmap f (Pair x y) = Pair (f x) (f y)

data Proxy a = Proxy  -- no elements
instance Functor Proxy where
    fmap f Proxy = Proxy

newtype Cont r a = Cont { runCont :: (a -> r) -> r }  -- element appears in a double-negative position
instance Functor (Cont r) where
    fmap f (Cont g) = Cont (g . (. f))

无论如何,我认为通用实例"的想法真的没有道理.该实例是您放置特定于类型的代码的地方. (它必须去某个地方!)

In any case, I don't think the idea of a "generic instance" really makes sense. The instance is where you put your type-specific code. (It has to go somewhere!)

如果您想花更少的精力编写Functor实例,则可以使用GHC的DeriveFunctor扩展名.

If you want to exert less effort in writing Functor instances you can use GHC's DeriveFunctor extension.

{-# LANGUAGE DeriveFunctor #-}

data Pair a = Pair a a deriving Functor

data Proxy a = Proxy deriving Functor

newtype Cont r a = Cont { runCont :: (a -> r) -> r } deriving Functor

这篇关于跨类型构造函数编写泛型仿函数实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆