Working with cryptic error messages from ReasonML when writing custom Decco decoders.

Murphy Randle
InstructorMurphy Randle

Share this video with your friends

Send Tweet
Published 4 years ago
Updated 3 years ago

Decco is a language extension that automatically generates JSON encoders and decoders from type signatures. When adding adding custom Decoders, the error messages that the compiler produces can be quite confusing. This lesson shows the viewer how to use explicit type signatures to narrow down where an error might be coming from in custom codec code. This same pattern can be applied whenever confusing error messages come from code that is written without explicit type signatures.

Instructor: [00:00] Here I've got a module that implements a custom Decco codec, but there's a compiler error. It's pretty confusing. Let's go ahead and run the compiler in the console so that we can read it a little better.

[00:10] You can see that they're saying, "We found a bug for you. No file name." That's confusing. That's happening because this is a PPX, a language extension. When it's running, it's not actually running in a file. It's running in memory in the compiler. Someday, hopefully, that error message will be better, but it's what we have right now.

[00:25] You can see that it's saying that we have a type of Js.Dict.t of JSON, that it wanted a float, and the incompatible parts are JSON and float. This isn't very helpful because I'm not doing anything with a Dict in here. This is actually a pretty confusing error message.

[00:39] What do we do in this case? Usually, we can help ourselves out substantially by adding type annotations to what's going on up here. You can see that up here I've said, "I have a function that takes JSON and returns a date. Down here, I have a function that takes a date and returns a float. I should be OK, right?"

[00:58] Well, let's go ahead and add our type signature to see. On the decode function, I'm going to say that this should be a Decco.decoder of t. We'll need to move that type t up to the top of the module so that it's in scope. Decco decoder of type t. No messages inside of this function. It looks like we're probably OK there.

[01:18] Now, down here, let t_encode is of type Decco.encoder of type t. Oh, look. Now we're getting some more helpful error messages. If we save the file, we can see over here in the console output that we're saying, "OK, we have a float, but we need JSON."

[01:36] What I've done here is, I've taken a date. I've turned it into a float, but I've forgotten to turn it into JSON. I can just go ahead and add the function to convert the float to JSON. All of my error messages go away. This is a general tactic for type level debugging when you're working with Reason.

[01:54] A lot of times, you can leave types off, which makes development fast, meaning leave explicit type annotations off. If you're running into weird compiler errors, start adding type signatures so that the compiler can be more useful and tell you more specifically where things are going wrong.