[Haskell-cafe] Updating code to work with vinyl 0.4

Mateusz Kowalczyk fuuzetsu at fuuzetsu.co.uk
Tue Aug 12 07:27:38 UTC 2014

On 08/11/2014 05:04 PM, adam vogt wrote:
> Hi Mateusz,
> You can write  'Foo :~> [t| Maybe String |] to make the generated code include a
>   type instance App ElF Foo = Maybe String
> Unfortunately the type of (:~>) includes some un-exported classes, so
> you have to dig into vinyl's source to see which arguments are
> actually allowed.
> I'm not sure exactly what you mean by
>> PlainRec ElF (ParentId ': '[])” works but is ugly
> But maybe it's worth just using the Data.Vinyl.Universe.Field (ex.
> http://lpaste.net/109203), if you would rather write
>   PlainRec ElField '["parent_id" ::: Maybe Integer])
> than,
>   PlainRec ElF '[ParentId]
> Or maybe you want to use Symbol together with your own universe:
>   makeUniverse' ''Symbol "ElF"
>   semantics ''ElF [ [t| "height" |] :~> [t| Maybe Int |] ]
>   -- type instance App ElF "height" = Maybe Int -- or just write those by-hand
>   height = Proxy :: Proxy "height" -- there seems to be no code
> generation in Vinyl for these
> which will give you a type like
>   PlainRec ElF '["parent_id"]
> Hopefully one of these options is not as ugly as the other.
> Regards,
> Adam


I have managed to migrate to 0.4, thank you very much with these
instructions. I'll outline what I ended up having to do in case anyone
stumbles upon this thread in the future.

I ended up going with makeUniverse' ''Symbol "ElF" way. This made the
migration fairly mechanical. The reason for going this way rather than
the others is that I don't have to define separate field type and mess
around with singletons. For my application, it's important to me that
the field names match up what they are in raw data so it was great I
could keep using these.

First I turned all

foo :: "foo" ::: Bar
foo = Field


foo :: Proxy "foo"
foo = Proxy

Easy with a macro.

Likewise, I was able to turn the old field code into the

[t| "foo" |] :~> [t| Bar |]

style through some emacs macros.

I also used ‘type R a = PlainRec ElF a’.

With all these things in place, I simply had to remove every occurance
of ‘ ::: SomeType’ and replace all ‘PlainRec whatever’ with ‘R
whatever’. I also had a single ‘Rec’ in a combinator I defined but that
also was easy to replace with ‘R’.

Once again, thanks for your help!

Mateusz K.

More information about the Haskell-Cafe mailing list