Skip to content

Instantly share code, notes, and snippets.

@gabejohnson
Last active October 13, 2017 21:20
Show Gist options
  • Save gabejohnson/c443284892806d7cf9654f3ecd40ca9e to your computer and use it in GitHub Desktop.
Save gabejohnson/c443284892806d7cf9654f3ecd40ca9e to your computer and use it in GitHub Desktop.
Potential solutions for multiple backend porting issues
-- Potential solutions for multiple backend porting issues
-- 1. Optional PS implementation for optional foreign imports
-- JS has an implementation, Erlang would export bar instead
module Foo (foo) where
-- import `fooImpl` if it's provided by the host implementation
optional foreign import foo :: Number -> Number -> Number
-- define it otherwise
foo x y = (bar x) + y
-- import `bar` if it's provided by the host implementation
optional foreign import bar :: Number -> Number
-- define it otherwise
bar x = x + baz
-- if both `foo` and `bar` have been defined, `baz` must be provided by the host implementation
optional foreign import baz :: Number
-- 2. Foreign type classes (follows on from default implementations).
-- a) define a `foreign` class
-- b) export dictionaries containing the appropriate implementations
-- Note: if a host exports `foo`, it needn't export `bar` or `baz` and so on
module Foo (foo) where
foreign import class Foo where
foo :: Number -> Number -> Number
foo x y = (bar x) + y
bar :: Number -> Number
bar x = x + baz
baz :: Number
-- 3. Import foreign modules
module Foo (foo) where
foreign import module FooImpl (foo :: Number -> Number -> Number)
-- JS exports foo, Erlang exports bar
-- FooImpl.purs
module FooImpl (foo) where
-- JS exports `foo`, Erlang does not
foreign import foo :: Number -> Number -> Number
foo x y = (bar x) + y
-- Erlang exports `bar`, JS does not
foreign import bar :: Number -> Number
-- Or keep delegating
module FooImpl (foo) where
foreign import module BarImpl (bar :: Number -> Number)
foreign import foo :: Number -> Number -> Number
foo x y = (bar x) + y
-- BarImpl.purs
module BarImpl (bar) where
-- Erlang exports `bar`, C++ does not
foreign import bar :: Number -> Number
bar x = x + baz
-- C++ exports `baz`, Erlang does not
foreign import baz :: Number
-- Userland
foreign import impl :: { foo :: Maybe (Number -> Number -> Number)
, bar :: Maybe (Number -> Number)
, baz :: Maybe Number
}
baz :: Number
baz = case impl.baz of
Just x -> x
Nothing -> crashWith "No implementation for foo, bar or baz"
bar :: Number -> Number
bar = maybe (_ + baz) id impl.bar
foo :: Number -> Number -> Number
foo = maybe (\x y -> (bar x) + y) id impl.foo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment