As an example, I can do something like the following:
data Foo = Foo (Variant (bar :: Int, baz :: Boolean))
type Bar v = (bar :: Int | v)
_bar = SProxy :: SProxy "bar"
bar :: forall v. Int -> Variant (Bar v)
bar = inj _bar
type Baz v = (baz :: Boolean | v)
_baz = SProxy :: SProxy "baz"
baz :: forall v. Boolean -> Variant (Baz v)
baz = inj _baz
someBar :: forall v. Variant (bar :: Int, baz :: Boolean | v) -> Maybe Foo
someBar =
default Nothing
# on _bar (Just <<< Foo <<< bar)
someBaz :: forall v. Variant (bar :: Int, baz :: Boolean | v) -> Maybe Foo
someBaz =
default Nothing
# on _baz (Just <<< Foo <<< baz)
> someBar $ bar 1 -- Just Foo
> someBar $ baz true -- Nothing
> someBaz $ bar 1 -- Nothing
> someBaz $ baz true -- Just Foo
However, I’d prefer to have each function only type check if it’s passed a row with the field it’s concerned about, like this:
someBar :: _ -> Foo
someBar = Foo
someBaz :: _ -> Foo
someBaz = Foo
> someBar $ bar 1 -- Foo
> someBar $ baz true -- Type error
> someBaz $ bar 1 -- Type error
> someBaz $ baz true -- Foo
It this possible?