Explaining rowtype example from YouTube clip Brave New World

In the following clip at 19:00 Brave new world he shows an example that looks like the following Record (Persistable Payment | Callbackable | r). Whatever I try I am not able to reproduce the syntax in a simple example. The only way I understand how to use rowtype is type MyType = forall r. {a::String | r}.

Can someone please explain how his example works with a simpler example and why am I not able to use a syntax like Record (Int | String | r)?

1 Like


the syntax with the curly braces { name :: String, age :: Int } is syntactic sugar for Record ( name :: String, age :: Int) (note that you still need the labels)

so something like this should work:

type MyRec r = Record ( name :: String, age :: Int  | r)

test :: forall r . Record ( name :: String, age :: Int | r) -> String
test r = r.name <> show r.age

res = test { name: "Dude", age: 42 }

There is a bit more about this in the docs

And there is a great section on more advanced usages of recors in Jordan’s Reference

Maybe this will help you further - if not feel free to ask :wink:

1 Like

PS in the example from the video the labels are in Persistable and the other parts:

type Persistable a =
    (persist :: a -> Aff Unit)

He seems to be using these as building-blocks/parts (with |) to put together records with fields from all those - to be honest I think I never used this (I love this but I never actually had the need) so I’m not sure but AFAIK it should still work (I think you’ll have to replace | with ‘+’ from RowApply?) more or less like this (there was a few changes to purescript and it’s syntax)


Ok it is probably that the syntax has changed then why I cant understand what he is doing. Thanks for the reply!

1 Like

I’m not 100% sure that | will not work (I did not try and I don’t actually know the syntax rules for these) - I think this does only work if left of the | is a "list of label :: type pairs though.

Can you share the code you tried? Maybe we can work it out together.

1 Like

What I have tried is from the example from the clip.

type Persistable a = (persist :: a -> Aff Unit)
tt :: forall r. Record (Persistable Int | String | r)
tt = ??? -- BTW is there a way in purescript to have an unimplemented function type check?

However this just gives me syntax error at the first |

There is undefined from the Undefined Package - but for just setting up something like this will work too

undefined :: forall a. a
undefined = go unit
  where go unit = go unit

And yes it seems you can do

tt :: forall r. Record ( label :: String | Persistable Int )

but not add | r

Once you import type (+) and change your Persistable a bit it works:

import Type.Row (type (+))

type Persistable a r = (persist :: a -> Unit | r)
tt :: forall r. Record ( label :: String | Persistable Int + r)
tt = undefined

this type-checks for me.

Of course this is a bit silly as + r is a bit like x + 0 in common arithmetic - so you could do

type Persistable a r = (persist :: a -> Unit | r)
tt :: forall r. Record ( label :: String | Persistable Int r )
tt = undefined

here too - but once you have more parts I’d go with +

PS: Don’t forget the label names :wink:

PPS: I guess you could generalize my last example there to Record ( moreLabals | ExtensionOne (ExtensionTwo (... ExtensionN r)...)) ) as was hinted in Jordan’s Reference.

1 Like

AFAIK, that’s not valid syntax. There were some major parser changes made in v0.13.0 which was released in May 2019. So, perhaps these guys were on a v0.12.x release?