purescript

How to have row without particular field as function param


What I want is following, I have a row type:

type FooBarBaz =
  ( foo :: Int
  , bar :: String
  , baz :: Boolean
  )

Then a need a function that takes this row type record but without "foo": and adds default "foo" field:

withoutFoo { bar: "bar", baz: true} -- > { foo: 1, bar: "bar", baz: true}

I tried to do something like this, but can not get it around:

withoutFoo :: ∀ r.
  Lacks "foo" r =>
  Cons "foo" Int r FooBarBaz =>
  { | r } -> { | FooBarBaz }
withoutFoo props = Record.union { foo: 1 } props

UPD:

managed to solve it with Union constraint:

withoutFoo :: ∀ r.
  Union r ( foo :: Int ) FooBarBaz =>
  { | r } -> { | FooBarBaz }
withoutFoo props =
  Record.merge props { foo: 1 }


Solution

  • The problem is that your function isn't actually generic. There is only one possible choice for r: it should always be (bar :: String, baz :: Boolean)

    So just make that the type of your function:

    withoutFoo :: { bar :: String, baz :: Boolean } -> { | FooBarBaz }
    withoutFoo props = Record.union { foo: 1 } props