Search code examples
exceptionffipurescript

purescript - modelling a function which throws an exception


Suppose I have a Javascript function f which throws an exception.

I'd like to expose it on the Purescript side as

foreign import f :: a -> Either e b

where e is the type of the thrown exception.

I could achieve this by catching the exception and wrapping the result of f with the constructors of Either, but it seems a dirty solution since I would use Purescript data constructors on the Javascript side.

Is there a better or more standard solution to this?


Solution

  • The usual way to go about constructing PureScript data from JavaScript is to pass the constructors in as functions. Your JS function would take extra two parameters:

    // JavaScript
    exports.f_ = left => right => a => {
        try { return right(whatever(a)); }
        catch(e) { return left(e); }
    }
    

    Then in PureScript you import the function, but do not export it to the consumers. Instead, make a wrapper that passes the Left and Right constructors, and export that:

    -- PureScript
    module MyModule(f) where
    
    foreign import f_ :: forall a b e. (e -> Either e b) -> (b -> Either e b) -> a -> Either e b
    
    f :: forall a e b. a -> Either e b
    f = f_ Left Right