根据Data类型类定义fmap

时间:2012-12-12 12:30:48

标签: haskell metaprogramming

可以根据Data.Data中的fmap类型类来定义Data吗?

似乎使用gfoldl无法修改类型..是否有其他组合器可以执行此操作?

我猜测在一般情况下无法完成 因为人们无法仅影响“RightaEither a a,但也许可以针对某些情况(例如Maybe

)执行此操作

(我知道fmap很容易导出,但我仍然对使用Data是否可以实现这一点感兴趣

1 个答案:

答案 0 :(得分:1)

以下是使用here

中的syb的示例
{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables, FlexibleContexts #-}
import Data.Generics
import Unsafe.Coerce

{- | C tags the type that is actually parameterized, so to avoid touching the
Int when a ~ Int:

> data T a = T Int a

by changing the type (not representation) to:

> x :: T Int (C Int)
-}
newtype C a = C a deriving (Data,Typeable)

fmapData :: forall t a b. (Typeable a, Data (t (C a)), Data (t a)) =>
    (a -> b) -> t a -> t b
fmapData f input = uc . everywhere (mkT $ \(x::C a) -> uc (f (uc x)))
                    $ (uc input :: t (C a))
    where uc = unsafeCoerce