This expression was expected to have type
'int'
but here has type
'string -> int' This expression was expected to have type
'int'
but here has type
'string -> int'But I got the error message
Error: This expression has type
((locl_ty * Tast.pos * ('ex, 'fb, 'en) Aast.expr_) list ->
Result_set.t)
list
but an expression was expected of type Result_set.t list
Type
(locl_ty * Tast.pos * ('ex, 'fb, 'en) Aast.expr_) list ->
Result_set.t
is not compatible with type Result_set.t
Which is not half as readable.You're right though that OCaml isn't the kind of language you can pick up in an afternoon.
Should that be “Result set type was expected”, not “list”?
means a list whose items are of type Result_set.t.
Also I think the notation X.t is idiomatic for a type defined by module X.
I don't know if you see a real readability issue or not, but I do think it's easy to jump to "hard to read" when that's only true in a certain parochial sense: it's not what we're used to.
I don't know OCaml really, but I would read that intuitively as a list of (functions that return Result_set.t), which is not compatible with a list of Result_set.t.
I built a reasonably popular typechecker for PHP, so I have some experience with the DX for these sorts of programs. I don't think it's good for a couple of ASCII characters and line breaks to be the difference between an acceptable and an unacceptable type annotation. It requires, as you say, for the OCaml type system to be burned into people's minds for them to immediately spot the issue.
In a similar context Rust will just say "function expected 5 arguments, you gave it 4" which has a very obvious remediation.
1. Error: This expression has type ('x -> Result_set.t) list but an expression was expected of type Result_set.t list
2. where 'x = (locl_ty * Tast.pos * ('ex, 'fb, 'en) Aast.expr_) list
The solution suggested by the parent of your post sounds desirable also, but perhaps the currying semantics of Ocaml makes that difficult or poorly-defined?
Dropping an example in TryOcaml[0]:
let f : int -> int = fun _ -> 1 ;;
val f : int -> int = <fun>
let ex : int list = [f] ;;
Line 1, characters 21-22:
Error: This expression has type int -> int but an expression was expected of type
int
[0]: https://try.ocamlpro.com/ myfun :: Int -> Char -> Bool
myfun a b = undefined
if you give too many arguments: myfun 1 'c' 3
• Couldn't match expected type ‘t0 -> t’ with actual type ‘Bool’
• The function ‘myfun’ is applied to three value arguments,
but its type ‘p10 -> Char -> Bool’ has only two
if you give too few arguments: putStrLn (myfun 1)
• No instance for (Show (p20 -> Bool))
arising from a use of ‘print’
(maybe you haven't applied a function to enough arguments?)
I like how it says applied to three value arguments ... but its type ... has only two
and maybe you haven't applied a function to enough arguments? > myfun 1 'c' 3
-- TOO MANY ARGS ---------------------------------------------------------- REPL
The `myfun` function expects 2 arguments, but it got 3 instead.
5| myfun 1 'c' 3
^^^^^
Are there any missing commas? Or missing parentheses?
> not (myfun 1)
-- TYPE MISMATCH ---------------------------------------------------------- REPL
The 1st argument to `not` is not what I expect:
5| not (myfun 1)
^^^^^^^
This `myfun` call produces:
a -> Bool
But `not` needs the 1st argument to be:
Bool
Besides being 'beginner friendly', this just takes away cognitive overhead when you can glance at an error message and immediately know what happened.(Edit: Formatting. Note that in the console output the arrows actually line up with the source of the errors)
I agree the first 6 months of this is mind-numbingly frustrating.
That's one of the top few specialties tasks for humans. After you learn it, you immediately know its meaning, it becomes easy with no thinking at all required.
Anyway, the plain English example from Elm on the sibling comment is much better, because it's already easy to understand before you learn to recognize it.
Is a lie fabricated to deflect criticism of the person who coined the term via abusive ad hominem of the critic.
Surprisingly, that tends to predict the quality of arguments invoking Stockholm syndrome pretty well, too.