跨类型构造函数编写泛型仿函数实例?

巴布拉·坎宁安(Babra Cunningham)

我正在学习基本的类型类,并functor为我的类型编写了自己的实现Test a(行为类似于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

是否有可能实现类似的东西:

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

错误:

Parse error in pattern: c

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

本杰明·霍奇森

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

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))

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

如果您想减少编写Functor实例的工作量,可以使用GHC的DeriveFunctor扩展名。

{-# 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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章