Re: help with some basic code that doesn't work
Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk> wrote:
Just a comment, since a couple of people have made similar statements. Haskell will derive Eq for arbitrarily complex types - there is no restriction to "simple" types, whatever they might be.
Now that this topic is brought up... Occasionally I would need to define recursive datatypes using an explicit fixed-point operator, such as:
data Fix f = In (f (Fix f)) deriving (Show, Eq) data L a x = Nil | Cons a x deriving (Show, Eq)
However, Haskell was not able to derive from Fix f any instances. The following is what happens in GHCi: *Main> In Nil == In Nil Context reduction stack overflow; size = 21 Use -fcontext-stack20 to increase stack size to (e.g.) 20 `Eq (L e (Fix (L e)))' arising from use of `==' at <interactive>:1 `Eq (Fix (L e))' arising from use of `==' at <interactive>:1 <<deleted>> *Main> In Nil Context reduction stack overflow; size = 21 Use -fcontext-stack20 to increase stack size to (e.g.) 20 `Show (L e (Fix (L e)))' arising from use of `print' at <interactive>:1 <<deleted>> Probably Malcolm meant that Haskell will derive standard instances for arbitrarily complex type **if they are definable manually**. If so Malcolm's statement is true -- indeed I cannot even declare the instances by hand. The following declaration is acceptable by GHC after using the option -fallow-undecidable-instances, but even though, I got the same error message as I try to print In Nil.
Instance Show (f (Fix f)) => Show (Fix f) where showsPrec _ (In x) = ("In ("++) . showsPrec 1 x . (')':)
This is rather unsatisfactory, because I would not be able to inspect values of type Fix f in the interpreter. Is there a way to get around this? sincerely, Shin
Shin-Cheng Mu <scm@ipl.t.u-tokyo.ac.jp> wrote:
Occasionally I would need to define recursive datatypes using an explicit fixed-point operator, such as:
data Fix f = In (f (Fix f)) deriving (Show, Eq) data L a x = Nil | Cons a x deriving (Show, Eq)
However, Haskell was not able to derive from Fix f any instances. The following is what happens in GHCi:
*Main> In Nil == In Nil
Context reduction stack overflow; size = 21
[...]
Instance Show (f (Fix f)) => Show (Fix f) where showsPrec _ (In x) = ("In ("++) . showsPrec 1 x . (')':)
This is rather unsatisfactory, because I would not be able to inspect values of type Fix f in the interpreter. Is there a way to get around this?
You have to tie the knot yourself --- unfortunately this involves re-coding the instance functors behind ``deriving''. I did this last summer for demonstration purposes --- you need only -fglasgow-exts for the ``deep instance'': \begin{code} module Fix where data Fix f = F (f (Fix f)) data L a b = L (Maybe (a,b)) deriving Show oParen = ('(' :) cParen = (')' :) parens shows = oParen . shows . cParen mkShowsPair showsA showsB (a,b) = parens $ showsA a . (", " ++) . showsB b mkShowsMaybe showsA Nothing = ("Nothing" ++) mkShowsMaybe showsA (Just a) = parens $ ("Just " ++) . showsA a mkShowsL showsA showsB (L m) = parens $ ("L " ++) . mkShowsMaybe (mkShowsPair showsA showsB) m mkShowsFix :: ((Fix f -> ShowS) -> (f (Fix f) -> ShowS)) -> (Fix f -> ShowS) mkShowsFix mkShowsF = showsF where showsF (F x) = parens $ ("F " ++) . mkShowsF showsF x showsFL :: (Show a) => Fix (L a) -> ShowS showsFL = mkShowsFix (mkShowsL shows) instance (Show a) => Show (Fix (L a)) where showsPrec _ = showsFL flEmpty = F (L Nothing) flCons x xs = F (L (Just (x,xs))) infixr 5 `flCons` \end{code} Wolfram
On Mon, Feb 14, 2005 at 02:31:54PM +0900, Shin-Cheng Mu wrote:
Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk> wrote:
Just a comment, since a couple of people have made similar statements. Haskell will derive Eq for arbitrarily complex types - there is no restriction to "simple" types, whatever they might be.
Now that this topic is brought up...
Occasionally I would need to define recursive datatypes using an explicit fixed-point operator, such as:
data Fix f = In (f (Fix f)) deriving (Show, Eq) data L a x = Nil | Cons a x deriving (Show, Eq)
However, Haskell was not able to derive from Fix f any instances.
[snip]
This is rather unsatisfactory, because I would not be able to inspect values of type Fix f in the interpreter. Is there a way to get around this?
sincerely, Shin
Funny this comes up at this time, as Fix was on-topic yesterday at #haskell. One way to make Fix an instance of Show/Eq is this (based on http://www.haskell.org/hawiki/PreludeExts, where Fix is called Rec): class RecShow f where recShow :: Show a => f a -> String instance (RecShow f) => Show (Rec f) where show (In x) = "(In (" ++ recShow x ++ "))" instance RecShow Maybe where recShow = show instance RecShow [] where recShow = show instance Show a => RecShow (Either a) where recShow = show Happy Hacking, Remi -- Nobody can be exactly like me. Even I have trouble doing it.
On Mon, Feb 14, 2005 at 12:36:22PM +0100, Remi Turk wrote:
Now that this topic is brought up...
Occasionally I would need to define recursive datatypes using an explicit fixed-point operator, such as:
data Fix f = In (f (Fix f)) deriving (Show, Eq) data L a x = Nil | Cons a x deriving (Show, Eq)
However, Haskell was not able to derive from Fix f any instances.
[snip]
This is rather unsatisfactory, because I would not be able to inspect values of type Fix f in the interpreter. Is there a way to get around this?
Funny this comes up at this time, as Fix was on-topic yesterday at #haskell. One way to make Fix an instance of Show/Eq is this (based on http://www.haskell.org/hawiki/PreludeExts, where Fix is called Rec):
It's even more funny - just yesterday I wanted to derive Show and Read for a similar datatype :) Best regards Tomasz -- Szukamy programisty C++ i Haskell'a: http://tinyurl.com/5mw4e
participants (4)
-
kahl@cas.mcmaster.ca -
Remi Turk -
Shin-Cheng Mu -
Tomasz Zielonka