origamitower / folktale

[not actively maintained!] A standard library for functional programming in JavaScript
https://folktale.origamitower.com/
MIT License
2.05k stars 102 forks source link

Match one case in union #220

Closed benjamingeorge closed 5 years ago

benjamingeorge commented 5 years ago

I'm new and confused on some usage. Given:

union("RemoteData", {
    INIT() {
        return {};
    },
    LOADING() {
        return {};
    },
    SUCCESS(data) {
        return { data };
    },
    ERROR(error) {
        return { error };
    }
}).derive(derivations.equality);

Lets say state = RemoteData.Success() with some data in it after a fetch call. Is there a way to just do a one line match to show/hide a button?

I tried state.equals(RemoteData.SUCCESS()) && <button /> but this doesn't work for the SUCCESS instance because of the data inside it (because of structural equality i'm guessing).
It will indeed work for INIT and LOADING since they don't contain any data or error.

Having to use matchWith for such simple cases seems like overkill, for example:

function showIcon(state, onClick) {
    return state.matchWith({
        INIT: () => {},
        LOADING: () => {},
        ERROR: ({ error }) => {},
        SUCCESS: ({ data }) => <SvgIcon icon={CloseIcon} onClick={onClick} />
    });
}

I'm hoping I'm just missing something with how the union adt can be used.

robotlolita commented 5 years ago

Yes, equals does a structural equality comparison.

The function you're looking for is the hasInstance (might be a confusing term for people not coming from the OO community?). It's added to all unions created through the adt module. There's a detailed explanation of hasInstance in the documentation, but what you're looking for is pretty much:

RemoteData.SUCCESS.hasInstance(state)

You can also alias this function without worrying about this:

const isSuccess = RemoteData.SUCCESS.hasInstance;

isSuccess(state)

This used to be a property in the instances, but that caused a lot of problems with nullable data and objects with similar properties, so it was moved to the constructor.

benjamingeorge commented 5 years ago

Awesome thanks!