Deriving Show for non-regular data types

Hi, As part of studying Okasaki's PFDS book, I wanted to add Show support for each of the data structures, and some have proven to be challenging, as some of the types are non-regular and automatic derivation of Show doesn't work. I've been able to add some code that introduces a supplementary type class that serves as a way to pass "proof" that the wrapping data type supports traversal for Show-ability, but the solution seems unsatisfactory. I would greatly appreciate any suggestions for improvements. I've attached the code; the relevant bits are in BankersDeque.hs, Example.hs, NestedShowable.hs, and SimpleCatenableDeque.hs. The same code is available here: https://gist.github.com/drvink/30fb2a2b257fc99af281 Thanks, Mark Laws -- |v\ /\ |\ |< |_ /\ \^| //

You may want to look at the Show1 class, which may or may not help you any.
You also may or may not find Ralf Hinze's paper "Numerical Representations
as Higher-Order Nested Datatypes" helpful. Nested types can be extremely
efficient in certain situations, and it's not *usually* too terribly hard
to read code that uses them, but writing it is an entirely different story.
In some cases, you can get good results using GADTs to enforce your shape
invariants, and they tend to be a lot easier to work with.
On Mar 11, 2015 1:45 AM, "Mark Laws"
Hi,
As part of studying Okasaki's PFDS book, I wanted to add Show support for each of the data structures, and some have proven to be challenging, as some of the types are non-regular and automatic derivation of Show doesn't work. I've been able to add some code that introduces a supplementary type class that serves as a way to pass "proof" that the wrapping data type supports traversal for Show-ability, but the solution seems unsatisfactory. I would greatly appreciate any suggestions for improvements. I've attached the code; the relevant bits are in BankersDeque.hs, Example.hs, NestedShowable.hs, and SimpleCatenableDeque.hs. The same code is available here:
https://gist.github.com/drvink/30fb2a2b257fc99af281
Thanks, Mark Laws
-- |v\ /\ |\ |< |_ /\ \^| //
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Hi Mark,
This combination seems to work:
instance (Show a, Show1 d) => Show (d a) where
showsPrec = showsPrec1
deriving instance (Show (d a), Show1 d)
=> Show (SimpleCatDeque d a)
But it needs overlapping instances. I don't see another way to express
(Show (d a), Show (d (d a)), Show (d (d (d a))), ... )
in a way that ghc will lazily evaluate the ...
Regards,
Adam
On Wed, Mar 11, 2015 at 1:59 AM, David Feuer
You may want to look at the Show1 class, which may or may not help you any. You also may or may not find Ralf Hinze's paper "Numerical Representations as Higher-Order Nested Datatypes" helpful. Nested types can be extremely efficient in certain situations, and it's not *usually* too terribly hard to read code that uses them, but writing it is an entirely different story. In some cases, you can get good results using GADTs to enforce your shape invariants, and they tend to be a lot easier to work with. On Mar 11, 2015 1:45 AM, "Mark Laws"
wrote: Hi,
As part of studying Okasaki's PFDS book, I wanted to add Show support for each of the data structures, and some have proven to be challenging, as some of the types are non-regular and automatic derivation of Show doesn't work. I've been able to add some code that introduces a supplementary type class that serves as a way to pass "proof" that the wrapping data type supports traversal for Show-ability, but the solution seems unsatisfactory. I would greatly appreciate any suggestions for improvements. I've attached the code; the relevant bits are in BankersDeque.hs, Example.hs, NestedShowable.hs, and SimpleCatenableDeque.hs. The same code is available here:
https://gist.github.com/drvink/30fb2a2b257fc99af281
Thanks, Mark Laws
-- |v\ /\ |\ |< |_ /\ \^| //
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

On Thu, Mar 12, 2015 at 12:25 PM, adam vogt
This combination seems to work:
instance (Show a, Show1 d) => Show (d a) where showsPrec = showsPrec1
deriving instance (Show (d a), Show1 d) => Show (SimpleCatDeque d a)
But it needs overlapping instances. I don't see another way to express
(Show (d a), Show (d (d a)), Show (d (d (d a))), ... )
in a way that ghc will lazily evaluate the ...
Hi Adam and David, Thanks for the tips. This works, but there's another issue now:
:load SimpleCatenableDeque.hs BankersDeque.hs import BankersDeque cons 1 (cons 2 empty ++ (cons 3 (cons 7 (cons 123 empty)))) ++ (cons 4 (cons 5 (empty) ++ (cons 6 (cons (-1) (cons 99 empty) ++ (cons 72 empty))) ++ (cons 44 empty ++ (cons 7 (cons 8 (cons 9 (cons 10 (cons 11 empty))))))) ++ cons 9 (cons 10 (cons 123 (empty :: SimpleCatDeque BankersDeque Int) ++ (cons 83 empty))))
<interactive>:28:1-315: No instance for (Show1 BankersDeque) arising from a use of 'print' In a stmt of an interactive GHCi command: print it What would the necessary instance look like for BankersDeque? Thanks, Mark -- |v\ /\ |\ |< |_ /\ \^| //

Hi Mark,
Adding this instance lets your example work:
instance Show1 BankersDeque where showsPrec1 = showsPrec
Regards,
Adam
On Thu, Mar 12, 2015 at 9:36 AM, Mark Laws
On Thu, Mar 12, 2015 at 12:25 PM, adam vogt
wrote: This combination seems to work:
instance (Show a, Show1 d) => Show (d a) where showsPrec = showsPrec1
deriving instance (Show (d a), Show1 d) => Show (SimpleCatDeque d a)
But it needs overlapping instances. I don't see another way to express
(Show (d a), Show (d (d a)), Show (d (d (d a))), ... )
in a way that ghc will lazily evaluate the ...
Hi Adam and David,
Thanks for the tips. This works, but there's another issue now:
:load SimpleCatenableDeque.hs BankersDeque.hs import BankersDeque cons 1 (cons 2 empty ++ (cons 3 (cons 7 (cons 123 empty)))) ++ (cons 4 (cons 5 (empty) ++ (cons 6 (cons (-1) (cons 99 empty) ++ (cons 72 empty))) ++ (cons 44 empty ++ (cons 7 (cons 8 (cons 9 (cons 10 (cons 11 empty))))))) ++ cons 9 (cons 10 (cons 123 (empty :: SimpleCatDeque BankersDeque Int) ++ (cons 83 empty))))
<interactive>:28:1-315: No instance for (Show1 BankersDeque) arising from a use of 'print' In a stmt of an interactive GHCi command: print it
What would the necessary instance look like for BankersDeque?
Thanks, Mark
-- |v\ /\ |\ |< |_ /\ \^| //
participants (3)
-
adam vogt
-
David Feuer
-
Mark Laws