2012-12-12 54 views
4

根據Data類型從Data.Data可以定義fmap嗎?根據數據類型定義fmap

看來,使用gfoldl一個不能修改類型..是否有其他的combinators可以做到這一點?

我猜它不能在一般情況下完成正如人們所沒有的只有在Either a a影響「Righta的方式,但或許可以對一些案件進行如Maybe

(我知道fmap很容易推導,但我仍然有興趣在這是否是可以實現使用Data

+3

有使用例如'syb'給出底部是[here](http://www.haskell.org/haskellwiki/Scrap_your_boilerplate)。它使用'unsafeCoerce';不知道是否有一個不那麼噁心的做法。 – jberryman

+0

@jberryman:你應該發佈這個答案。 – sclv

回答

1

這裏有一個例子使用sybhere

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