mlhaufe/brevity

Improve the parameterized data situation

Closed this issue · 0 comments

Parameterized types are too awkward to use with traits and complect:

const ListData = data((List, T) => ({
    Nil: {},
    Cons: { head: T, tail: List(T) }
}))

const fromArray = trait(ListData, (family) => ({
    _(self, ...xs) {
        return xs.reduceRight((acc, x) => family.Cons(x, acc), family.Nil)
    }
}))

TypeError: Invalid dataDef declaration. Did you forget to call with a parameter?

Traits require instantiation of the data decl which is not a good experience and is not a good practice either. What is a valid type to pass?

The same situation happens with complect:

const List = complect(ListData(?), {fromArray})

How is List(Number) then used by the client consistently?

The first thought is to just delay trait and data initialization to when complect is used.

The problem though is that currently data and trait are usable independently:

const color = data({ Red: {}, Green: {}, Blue: {} }),
    {Red, Green, Blue} = color

const print = trait(color, {
    Red() { return '#FF0000' },
    Green() { return '#00FF00' },
    Blue(){ return '#0000FF' }
})

print(Red) // '#FF0000'

So the function call form would be lost.

This implies the partial application functionality would also be lost:

const length = foldRight(_, (x, acc) => acc + 1, 0)

But maybe that's not too bad. If trait is late-bound then that might look like:

const length = trait({
    _: (xs) => xs.foldRight((x, acc) => acc + 1, 0)
})