Last active
October 13, 2017 21:20
-
-
Save gabejohnson/c443284892806d7cf9654f3ecd40ca9e to your computer and use it in GitHub Desktop.
Potential solutions for multiple backend porting issues
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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