Ticket #1571 (closed bug: fixed)

Opened 6 years ago

Last modified 4 years ago

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

Reported by: sciolizer@… Owned by:
Priority: normal Milestone:
Component: libraries/base Version: 6.6.1
Keywords: synthesize,syb Cc:
Operating System: Linux Architecture: x86
Type of failure: Difficulty: Easy (less than 1 hour)
Test Case: Blocked By:
Blocking: Related Tickets:

Description (last modified by simonpj) (diff)

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

Change History

Changed 6 years ago by simonpj

  • status changed from new to closed
  • resolution set to fixed
  • description modified (diff)

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

Simon

Changed 4 years ago by simonmar

  • difficulty changed from Easy (1 hr) to Easy (less than 1 hour)
Note: See TracTickets for help on using tickets.