roc icon indicating copy to clipboard operation
roc copied to clipboard

Default values in Record don't work as expected

Open rudolfvesely opened this issue 1 year ago • 4 comments

Hi everybody,

I'm using the most current ROC (build from Nix flake).

This should work:

something = \foo, { firstBar ? Both, secondBar } ->
    when firstBar is
        Start -> Str.concat secondBar foo
        End -> Str.concat foo secondBar
        Both ->
            foo
            |> something { firstBar: Start, secondBar }
            |> something { firstBar: End, secondBar }
expect
    x = something "aaa" { secondBar: "bbb" }
    x == "bbbaaabbb"

But it doesn't:

# This 2nd argument to something has an unexpected type:
#
# 30│      x = something "aaa" { secondBar: "bbb" }
#                              ^^^^^^^^^^^^^^^^^^^^
#
# The argument is a record of type:
#
#     { … }
#
# But something needs its 2nd argument to be:
#
#     { firstBar : [
#         Both,
#         End,
#         Start,
#     ], … }
#
# Tip: Looks like the firstBar field is missing.

Thank you.

rudolfvesely avatar Aug 27 '24 09:08 rudolfvesely

Thanks for reporting this @rudolfvesely, I think this should indeed work.

As a workaround you can add this type annotation to fix it:

something : Str, { firstBar ? [Both, End, Start], secondBar : Str } -> Str

Note for future investigator, this version does work:

something = \foo, { firstBar ? Both, secondBar } ->
    when firstBar is
        Start -> Str.concat secondBar foo
        End -> Str.concat foo secondBar
        Both ->
            Str.concat foo secondBar
            
expect
    x = something "aaa" { secondBar: "bbb" }
    x == "aaabbb"

Anton-4 avatar Aug 27 '24 10:08 Anton-4

something : Str, { firstBar ? [Both, End, Start], secondBar : Str } -> Str

Thank you @Anton-4 , that works:

something : Str, { firstBar ? [Both, End, Start], secondBar : Str } -> Str
something = \foo, { firstBar ? Both, secondBar } ->
    when firstBar is
        Start -> Str.concat secondBar foo
        End -> Str.concat foo secondBar
        Both ->
            foo
            |> something { firstBar: Start, secondBar }
            |> something { firstBar: End, secondBar }
expect
    x = something "aaa" { secondBar: "bbb" }
    x == "bbbaaabbb"

But this doesn't even with the signature:

something : Str, { firstBar ? [Both, End, Start], secondBar : Str } -> Str
something = \foo, takethis ->
    { firstBar ? Both, secondBar } = takethis
    when firstBar is
        Start -> Str.concat secondBar foo
        End -> Str.concat foo secondBar
        Both ->
            foo
            |> something { takethis & firstBar: Start }
            |> something { takethis & firstBar: End }
expect
    x = something "aaa" { secondBar: "bbb" }
    x == "bbbaaabbb"

# Something is off with this record update:
# 37│              |> something { takethis & firstBar: Start }
#                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#
# This takethis value is a:
#
#     { firstBar ? […], … }
#
# But this update needs it to be compatible with:
#
#     { firstBar : […], … }

rudolfvesely avatar Aug 27 '24 13:08 rudolfvesely

Interesting, I'll open a second issue for that because that could be unrelated.

Anton-4 avatar Aug 27 '24 14:08 Anton-4

Likely cause

Anton-4 avatar Aug 28 '24 09:08 Anton-4