roc-lang / roc

A fast, friendly, functional language.
https://roc-lang.org
Universal Permissive License v1.0
4.46k stars 313 forks source link

improve confusing type mismatch InternalTask vs Task #6940

Open Anton-4 opened 3 months ago

Anton-4 commented 3 months ago
── TYPE MISMATCH in examples/helloWorld.roc ────────────────────────────────────

This 1st argument to this function has an unexpected type:

13│      args |> List.dropFirst 1 |> List.map parseNumber!
                                              ^^^^^^^^^^^

This parseNumber value is a:

    (Str -> Task.Task (Int Unsigned8) [Exit (Num *) Str])

But this function needs its 1st argument to be:

    InternalTask.Task a b

Tip: Type comparisons between an opaque type are only ever equal if
both types are the same opaque type. Did you mean to create an opaque
type by wrapping it? If I have an opaque type Age := U32 I can create
an instance of this opaque type by doing @Age 23.

A type mismatch like this where the user sees InternalTask.Task vs Task.Task is confusing because this is a visual difference that does not actually matter. This may be better with https://github.com/roc-lang/roc/pull/6836, this should be investigated.

Code to trigger this type mismatch:

app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br" }

import pf.Stdout
import pf.Task
import pf.Arg

parseNumber = \arg ->
    when Str.toU8 arg is
      Ok number -> Task.ok number
      Err msg -> Task.err (Exit 1 "Invalid argument \"${arg}\": ${msg}")

parseNumbers = \args ->
    args |> List.dropFirst 1 |> List.map parseNumber!

main =
    numbers = Arg.list! {} |> parseNumbers!
    total = List.sum numbers
    Stdout.line! "Sum of numbers: $(Num.toStr total)"