Reputation: 24814
Can one define fmap
in terms of the Data
typeclass from Data.Data
?
It seems that using gfoldl
one could not modify types.. Are there other combinators which can do this?
I'm guessing that it can't be done in the general case as one would have no way of only affecting the "Right
" a
's in an Either a a
, but perhaps it could be done for some cases such as Maybe
?
(I know that fmap
is easily derivable but am still interested in whether this is achievable using Data
)
Upvotes: 4
Views: 163
Reputation: 16645
Here's on example using syb
from here
{-# 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
Upvotes: 1