Stream: beginners

Topic: Type annotation with backpassing


view this post on Zulip mkrieger1 (Dec 30 2023 at 20:27):

We can add a type annotation to a definition by writing it above:

foo : Foo
foo = bar

However when using backpassing (typically with Result.try) this does not work (the compiler emits a "duplicate name" error, which makes sense when desugaring the backpassing – the first foo would be in the scope where bar is called and the second foo is the argument of bar and would shadow it, which is not allowed):

foo : Foo
foo <- bar |> Result.try

I have worked around this so far by writing:

foo <- bar |> Result.try
checkFoo : Foo
checkFoo = foo

This lets me ensure that I made bar return what I think it should return, but adds an "unused definition" warning.

Is there a better way? Maybe something like expect type foo == Foo (but I don't want a runtime check).

view this post on Zulip mkrieger1 (Dec 30 2023 at 20:39):

Maybe foo : Foo should not count as "definition" of foo?

view this post on Zulip Luke Boswell (Dec 30 2023 at 20:57):

I wonder if thd shadowing proposal would be helpful for this use case? Maybe that would work as it would be the same foo.

view this post on Zulip Brendan Hansknecht (Dec 30 2023 at 21:21):

:thinking:

view this post on Zulip Brendan Hansknecht (Dec 30 2023 at 21:21):

Do you normally type lambda parameters?

view this post on Zulip Brendan Hansknecht (Dec 30 2023 at 21:22):

Like when writing a quick List.map function

view this post on Zulip Brian Carroll (Dec 30 2023 at 22:48):

I do sometimes in Haskell. Not very often but sometimes.

view this post on Zulip Brendan Hansknecht (Dec 30 2023 at 23:02):

To clarify why I ask, anything that works with backpassing probably should also work with generic lambdas passed to something like List.map

If we enable:

foo: Foo
foo <- bar |> Result.try
...

We also by default enable

foo: Foo
bar |> Result.try \foo ->
    ...

view this post on Zulip Brian Carroll (Dec 30 2023 at 23:47):

Yes exactly.
In Haskell you can put the type inline with parentheses. In Roc that might look like this

bar |> Result.try \(foo: Foo) ->

Or

(foo: Foo) <- bar |> Result.try

view this post on Zulip Luke Boswell (Dec 30 2023 at 23:52):

If our arguments are comma delimited, could we do the same without parens?

view this post on Zulip Luke Boswell (Dec 30 2023 at 23:54):

Maybe it would be good to have inline type annotations for smaller functions or lambdas.


Last updated: Jul 06 2025 at 12:14 UTC