Problem
I made my first small mistake and Morel responded with three screens of text. I want a quick translation guide so I can fix it and move on.
Example
Add a string to a number and see what Morel says:
val x = 1 + "two";
0.0-0.0 Error: Cannot deduce type: conflict: int vs string
raised at: 0.0-0.0
What's happening
Morel's type errors read like a telegram, but there's always a verb
and a subject. "Cannot deduce type" is the verb — type inference
didn't converge. "Conflict: int vs string" is the subject — two
expressions were unified and one wants an int and one wants a
string. In this case + is polymorphic over numeric types and so
gets pinned to int by the literal 1, then the "two" on the right
is asked to be an int and refuses.
The fix is always the same: find which expression drove the first
constraint and which one disagreed. Here the 1 goes first because
it's on the left of +. Change either side to match and it compiles.
Two other errors you'll hit in the first hour:
val row = { id = 1, product = "Earl Grey", quantity = 12 };
row.prodcut;
Error: no field 'prodcut' in type '{id:int, product:string, quantity:int}'
This one is a gift. Morel prints the whole record type so you can see the fields it does know about, misspelled or otherwise. Copy the name from the error message rather than retyping it.
ordders;
Error: unbound variable or constructor: ordders
A plain unbound is almost always a typo or an out-of-order binding.
Morel evaluates top to bottom, so if val orders = … comes after the
ordders reference, fix the order.
One thing Morel will not help with yet: when you forget a trailing
; on a val, the REPL keeps reading the next line as if it were
part of the previous expression. The prompt changes from - to =.
That's your hint — type ; and hit enter to eject.
Variations
Position numbers in errors aren't always populated. 0.0-0.0 means
"the location was lost" — usually because the problem came from type
inference across expressions, not a single token. Don't chase the
number when it's zero; read the message.
See also
- Recipe 01 — First query — has the kind of snippet that will generate these errors if you fumble it.
- Recipe 02 — Values, records, and lists — what the
{id:int, ...}shape in the error actually means.