-- | Build a term and use a generic function for subterms
fromConstrB :: Data a
            => (forall d. Data d => d)
            -> Constr
            -> a
fromConstrB f = unID . gunfold k z
 where
  k :: forall b r. Data b => ID (b -> r) -> ID r
  k c = ID (unID c f)
 
  z :: forall r. r -> ID r
  z = ID


-- | Monadic variation on 'fromConstrB'
fromConstrB :: Data a
            => (forall d. Data d => d)
            -> Constr
            -> a
fromConstrB f = unID . gunfold k z
 where
  k :: forall b r. Data b => ID (b -> r) -> ID r
  k c = ID (unID c f)
 
  z :: forall r. r -> ID r
  z = ID


-- | Monadic variation on 'fromConstrB'
fromConstrB f = unID . gunfold k z
 where
  k :: forall b r. Data b => ID (b -> r) -> ID r
  k c = ID (unID c f)
 
  z :: forall r. r -> ID r
  z = ID


-- | Monadic variation on 'fromConstrB'