[GHC] #1571: type of synthesize in Data.Generics.Schemes is too restrictive

GHC trac at galois.com
Wed Aug 1 08:57:46 EDT 2007


#1571: type of synthesize in Data.Generics.Schemes is too restrictive
------------------------------------+---------------------------------------
    Reporter:  sciolizer at gmail.com  |        Owner:             
        Type:  bug                  |       Status:  closed     
    Priority:  normal               |    Milestone:             
   Component:  libraries/base       |      Version:  6.6.1      
    Severity:  normal               |   Resolution:  fixed      
    Keywords:  synthesize,syb       |   Difficulty:  Easy (1 hr)
          Os:  Linux                |     Testcase:             
Architecture:  x86                  |  
------------------------------------+---------------------------------------
Changes (by simonpj):

  * resolution:  => fixed
  * status:  new => closed

Old description:

> 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))

New description:

 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))
 }}}

Comment:

 Fair enough.  `synthesize` does indeed have the more general type, so I've
 generalised it as you suggest.

 Simon

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/1571>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the Glasgow-haskell-bugs mailing list