Type Lambdas in Gofer
The code in "Bananas in Space: Extending Fold and Unfold to Exponential Types" http://citeseer.ist.psu.edu/293490.html mirror: http://www.cs.nott.ac.uk/~gmh/bananas.pdf uses Gofer, and has examples such as data Rec f = In (f (Rec f)) type P f a = f (Rec f, a) mapP :: Functor f => (a -> b) -> P f a -> P f b mapP g = fmap (\(x,a) -> (x, g a)) instance Functor f => Functor (P f) where fmap = mapP Why did Gofer have this power while Haskell does not? Jim
Jim Apple wrote:
data Rec f = In (f (Rec f)) type P f a = f (Rec f, a)
mapP :: Functor f => (a -> b) -> P f a -> P f b mapP g = fmap (\(x,a) -> (x, g a))
instance Functor f => Functor (P f) where fmap = mapP
Why did Gofer have this power while Haskell does not?
Haskell does have the same power as Gofer, it simply does not allow you to define instances for type synonyms (just in order to prevent overlapping instances, I guess). If you use a newtype instead of a type synonym everything works fine: data Rec f = In (f (Rec f)) newtype P f a = P (f (Rec f, a)) unP (P x) = x mapP :: Functor f => (a -> b) -> P f a -> P f b mapP g = P . fmap (\((x,a)) -> (x, g a)) . unP instance Functor f => Functor (P f) where fmap = mapP Wolfgang
On Wed, Aug 01, 2007 at 07:57:48AM +0200, Wolfgang Lux wrote:
Jim Apple wrote:
data Rec f = In (f (Rec f)) type P f a = f (Rec f, a)
mapP :: Functor f => (a -> b) -> P f a -> P f b mapP g = fmap (\(x,a) -> (x, g a))
instance Functor f => Functor (P f) where fmap = mapP
Why did Gofer have this power while Haskell does not?
Haskell does have the same power as Gofer, it simply does not allow you to define instances for type synonyms (just in order to prevent overlapping instances, I guess). If you use a newtype instead of a type synonym everything works fine:
Quite probably they never bothered to test it. stefan@stefans:/usr/local/src/gofer$ tail -15 standard.prelude openfile f = primFopen f (error ("can't open file "++f)) id -- End of Gofer standard prelude: -------------------------------------------- class Functor f where fmap :: (a -> b) -> f a -> f b data Rec f = In (f (Rec f)) type P f a = f (Rec f, a) mapP :: Functor f => (a -> b) -> P f a -> P f b mapP g = fmap (\(x,a) -> (x, g a)) instance Functor f => Functor (P f) where fmap = mapP stefan@stefans:/usr/local/src/gofer$ src/gofer Gofer Version 2.30b Copyright (c) Mark P Jones 1991-1995 Reading script file "standard.prelude": ERROR "standard.prelude" (line 874): Not enough arguments for type synonym "P" FATAL ERROR: Unable to load prelude stefan@stefans:/usr/local/src/gofer$ Stefan
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 - -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Wolfgang,
Why did Gofer have this power while Haskell does not?
Quite probably they never bothered to test it.
More probably ;-) they did test it and just swept it under the carpet in order not to pollute the paper with this detail. From a theoretical point of view, one could argue that it indeed does not matter all that much here. Cheers, Stefan - -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (Darwin) iD8DBQFGsMcQX0lh0JDNIpwRAsGfAJ9q01MGgxY0/xuQSVuEVcIbrdMvmgCffYrS OVgdcXXgDpcneXGxAw+VF4g= =EeQ2 - -----END PGP SIGNATURE----- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (Darwin) iD8DBQFGsMcUX0lh0JDNIpwRAicdAKCA66w62+V+yKRpYjV86BbnNSMQpwCcDghZ t+G0sPzvIfdVaSO5pLLwNos= =H1MX -----END PGP SIGNATURE-----
participants (4)
-
Jim Apple -
Stefan Holdermans -
Stefan O'Rear -
Wolfgang Lux