可以fmap
根据Data
类型类定义Data.Data
吗?
似乎使用gfoldl
一个不能修改类型。还有其他组合器可以做到这一点吗?
我猜它不能在一般情况下完成,因为一个人无法只影响 " Right
"a
在 an 中Either a a
,但也许它可以在某些情况下完成,例如Maybe
?
(我知道这fmap
很容易推导,但我仍然对使用 是否可以实现感兴趣Data
)
可以fmap
根据Data
类型类定义Data.Data
吗?
似乎使用gfoldl
一个不能修改类型。还有其他组合器可以做到这一点吗?
我猜它不能在一般情况下完成,因为一个人无法只影响 " Right
"a
在 an 中Either a a
,但也许它可以在某些情况下完成,例如Maybe
?
(我知道这fmap
很容易推导,但我仍然对使用 是否可以实现感兴趣Data
)
这是使用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