natefaubion/adt.js

Apparently incorrect constraint when using macros on enum type

Opened this issue · 1 comments

Caveat: I just started experimenting with adt.js today, so hopefully this is just my misunderstanding of how to use adt.js and the macros...

When I try to constrain a field to restrict it to a previously declared enum type, the macro expansion results in an InvocationException when creating an instance of my newtype. If I define the newtype directly in JS (without using the sweet.js macros), everything works as expected.

Minimal example, which can be run in node after passing through sjs:

var adt = require('adt');

    enum FontWeight {
      normal = 'normal',
      bold = 'bold'
    }

    // No macros, this works as expected:
    var GoodFontSpec = adt.newtype({
      weight: adt.only(FontWeight) 
    });

    // This does not seem to wrap FontWeight in adt.only in the generated code,
    // resulting in a BadInvocation exception when trying to instantiate
    newtype BadFontSpec {
        weight: FontWeight
    }

    // instantiation:
    var gfs = GoodFontSpec(FontWeight.bold);

    console.log("gfs: ", gfs);

    // This will choke with an InvocationException:
    var bfs = BadFontSpec(FontWeight.bold);

As the comment mentions, I've looked at the generated code, and the issue appears to be that the macro expansion passes FontWeight directly as the second argument to field, when I think it should be wrapping this in adt.only().

Interesting. It seems like there's a test that covers this, but maybe the newtype is messing with it.
https://github.com/natefaubion/adt.js/blob/master/test/macros.sjs#L69

If macros are your thing, I'd suggest you checkout https://github.com/natefaubion/adt-simple which doesn't require a runtime (unless you want it for the derivers).