As the original poster, perhaps I should expand on my original grumble. My reasoning is clearly not correct below, but it was (as far as I remember) my actual thought process.
Bear in mind I’ve got plenty of experience over the decades in various languages from 8 bit assemblers through all the normal ones to a bit of Smalltalk and Lisp and a smattering of Haskell. I’m used to debugging and I’m used to not always having the greatest of error messages.
Expected: type "('a, unit, string, node) format4"
Actual: constructor "::", which is incompatible with type "format6"
So - as it happens I knew that what this means (at my level of understanding) is “bad format string”. That’s because I’ve seen similar before and was reduced to the make-random-change-until-something-happens process to get past it. Then I figured out that 9 times out of 10 (for me) it’s a missing-semicolon situation.
So, I tried to be a good citizen and checked the source-code of the library:
let textarea attrs fmt = text_tag "textarea" attrs fmt
So - that’s not hugely helpful because it’s clearly looking for a fmt
which doesn’t match the error-message in any sense and also isn’t defined in the library. (I’m checking this on github if that matters).
OK - so let’s try and decode the type: format4
is clearly formatting related and since there are 4 parameters listed in front of it I can guess what the number might be.
The first two parameters: 'a unit
- useless. Utterly without meaning. The first one clearly can be “anything” and the second one is… “unit”? This format4
expects 4 parameters and the second has to be the empty type - either the author is mad or I’m missing something fairly important here. (we all know it’s the second one, but what don’t I understand that would make this make sense)
OK - third parameter is string
- doesn’t tell me much. It might be related to the actual "%s"
stuff for formatting but it’s in the wrong place. If it isn’t representing the formatting string though, I’ve got no idea.
Last parameter-type node
sounds like something HTML-y and indeed it is defined in the library! it’s a tag or text or comment - that makes sense.
OK - so the two key problems from the “expected” part of the error message are:
- The type in the library I’m calling:
fmt
isn’t mentioned anywhere in the error.
- The type that is mentioned requires elements that don’t seem to make sense to provide and actually just don’t make any sense at all at my level of understanding (“anything” and “nothing”).
For the “actual” part of the error message.
First time reading it I missed the implication of ::
being list constructor altogether. Just read it as Constructor <punctuation> is incompatible...
. Didn’t even pick up on what the punctuation was.
The bit I focused on at first was format6
. Because one thing I certainly wasn’t trying to do was format 6 values or anything like that. Any way you cut it there was one “thing” involved. Either the list is the one thing or the fact that it has a single element is. Where the other 5 things are coming from - no idea.
Inside my list I have txt "%s" c.notes
and here is the definition for the txt tag:
let txt ?(raw = false) fmt = ...
OK, so it takes an optional “raw” which I’m not supplying and… one parameter which is fmt
.
That seems to be the same fmt
which is identified with format4
in the first part of the error and is supposed to take 4 parameters of which two make no sense.
At this point my ability/willingness to drill any deeper is gone.
To summarise:
- We have a single parameter
fmt
in the library’s source code
- The compiler thinks that should actually be a complex type with 4 parameters of its own
- It thinks I’ve somehow provided a complex type with 6 parameters (or rather I haven’t done so properly)
- But it also thinks
txt <format4> == <format6>
in some way. Where the extra two parameters are coming from is unclear.
- Neither of the types mentioned in the error message are defined in the library’s .ml file
- The merlin type hints in vim just repeat what the compiler error is telling me (which is fair enough, if it had better errors than the compiler you’d just copy that code to the compiler)
- I don’t think the dream-html library is at any fault here - it seems like plainly written code and has docs and examples.
Now, like I said I knew that what this error actually meant was “you’ve messed up a format string” which usually means a missing semicolon or something. In this case it wasn’t just a semicolon and trying to actually understand the root cause got me nowhere.
Hopefully it’s just me going down the wrong path or using the wrong tools or something. Or maybe format-string handling is always going to be a complex piece of library code that generates complex errors and I got unlucky. I have to say that for my own code (with its frankly pedestrian types) the error messages pretty much just say exactly what I need to change.
HTH