Skip to content

type of synthesize in Data.Generics.Schemes is too restrictive

The type of the synthesize function in Data.Generics.Schemes is unnecessarily restrictive. It's current type is

synthesize :: s  -> (s -> s -> s) -> GenericQ (s -> s) -> GenericQ s

but it would be more useful if it were

synthesize :: s -> (t -> s -> s) -> GenericQ (s -> t) -> GenericQ t

Below is a contrived example demonstrating why one might want the more liberal type.

module Main where

import Data.Generics

synthesize' :: s -> (t -> s -> s) -> GenericQ (s -> t) -> GenericQ t
synthesize' z o f x = f x (foldr o z (gmapQ (synthesize' z o f) x))

-- The toTree function fails to type if synthesize' is replaced
-- with synthesize.

data ConstructorTree = ConstructorTree String [ConstructorTree]
                     deriving (Show)

toTree :: Data a => a -> ConstructorTree
toTree = synthesize' [] (:) 
            (\a s -> ConstructorTree (showConstr (toConstr a)) s)

data Foo = Bar String | Baz Foo Int deriving (Data,Typeable)

main = print (toTree (Baz (Bar "12") 5))
Edited by Simon Peyton Jones
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information