[Haskell-cafe] Re: Adding a field to a data record

Iavor Diatchki iavor.diatchki at gmail.com
Tue Jul 28 12:37:11 EDT 2009


Hello,
you may also find the package "pretty-show"
(http://hackage.haskell.org/package/pretty-show) useful.  It contains
code to convert automatically derived instances of "Show" into an
explicit data structure, which you can then manipulate (e.g., by
adding the extra field), and then render back to text.
-Iavor


On Tue, Jul 28, 2009 at 6:07 PM, Malcolm
Wallace<Malcolm.Wallace at cs.york.ac.uk> wrote:
>> the part I would really like to avoid is writing the
>> New.Foo { a=a, b=b, ... z=1 } part, where the field
>> names are many, long, and varied.
>
> OK, here is another hack-ish trick, since I notice your data is stored on
> disk as text, using "show".  I assume you are using something like Read to
> retrieve it.  Well, how about using a real parser instead?  The parser
> during conversion can be slightly more lax, automatically adding in the
> extra field.
>
> For instance, using polyparse's Text.Parse, and DrIFT to derive the
> appropriate Parse instance for your datatype:
>
>    module Foo where
>    data Foo = Foo { a :: Int
>                   , b :: Bool
>                   , c :: Maybe Foo }
>      {-! derive : Parse !-}
>
> DrIFT gives you this instance:
>
>    {-* Generated by DrIFT : Look, but Don't Touch. *-}
>    instance Parse Foo where
>        parse = constructors
>            [ ( "Foo"
>              , return Foo `discard` isWord "{" `apply` field "a"
>                       `discard` isWord "," `apply` field "b"
>                       `discard` isWord "," `apply` field "c"
>                       `discard` isWord "}"
>              )
>            ]
>
> Let's say the field 'b' is new, and your existing data does not have it.  So
> just take the parser generated by DrIFT and make a small modification:
>
>    {-* Generated by DrIFT but modified by hand for conversion purposes *-}
>    instance Parse Foo where
>        parse = constructors
>            [ ( "Foo"
>              , return Foo `discard` isWord "{" `apply` field "a"
>                       `apply` return True -- this field does not yet exist
> in data
>                       `discard` isWord "," `apply` field "c"
>                       `discard` isWord "}"
>              )
>            ]
>
> Then do the obvious thing: parse the old data, immediately write it out
> again, and then throw away the modified parser in favour of the pure
> generated one.
>
> Regards,
>    Malcolm
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list