Skip to content

Instantly share code, notes, and snippets.

@ajnsit
Last active September 27, 2020 17:09
Show Gist options
  • Save ajnsit/987d57f0ab5d6ff545a4909aaf5cbdf2 to your computer and use it in GitHub Desktop.
Save ajnsit/987d57f0ab5d6ff545a4909aaf5cbdf2 to your computer and use it in GitHub Desktop.
Testing Purescript's Erlang Backend (https://github.com/purerl/purerl). Comparison with Caramel (https://github.com/AbstractMachinesLab/caramel) for OCaml -> Erlang conversion.
module Main where
import Control.Bind (bind, discard)
import Data.Function (($))
import Data.Maybe (Maybe(..))
import Data.Semigroup ((<>))
import Data.Show (show)
import Data.Unit (Unit)
import Effect (Effect)
import Effect.Class.Console (log)
import Erl.Process (SpawnedProcessState, spawn, (!))
data Msg = Reset | Add Int | Hello String
data State = State String Int
showState :: State -> String
showState (State s i) = "State (" <> show s <> ", " <> show i <> ")"
handle_message :: State -> Maybe Msg -> State
handle_message (State x y) msg =
case msg of
Just Reset -> State "" 0
Just (Add z) -> State x z
Just (Hello n) -> State n y
Nothing -> (State x y)
loop :: forall a. State -> SpawnedProcessState (Maybe Msg) -> Effect a
loop state recv = do
log ("current_state: " <> showState state)
msg <- recv.receiveWithTimeout 5000 Nothing
loop (handle_message state msg) recv
main :: Effect Unit
main = do
p <- spawn $ loop $ State "hi" 0
p ! (Just (Hello "joe"))
% Generated by purs version 0.0.7
-module(main@ps).
-export(['State'/0, 'Reset'/0, 'Add'/0, 'Hello'/0, showState/0, showState/1, handle_message/0, handle_message/2, loop/0, loop/2, main/0]).
-compile(nowarn_shadow_vars).
-compile(nowarn_unused_vars).
-compile(nowarn_unused_function).
-compile(no_auto_import).
-file("/Volumes/Dev/foss/purescript-erlang-backend-test/src/Main.purs", 15).
'State'() -> fun (Value0) ->
fun (Value1) ->
{ state, Value0, Value1 }
end
end.
-file("/Volumes/Dev/foss/purescript-erlang-backend-test/src/Main.purs", 13).
'Reset'() -> { reset }.
-file("/Volumes/Dev/foss/purescript-erlang-backend-test/src/Main.purs", 13).
'Add'() -> fun (Value0) ->
{ add, Value0 }
end.
-file("/Volumes/Dev/foss/purescript-erlang-backend-test/src/Main.purs", 13).
'Hello'() -> fun (Value0) ->
{ hello, Value0 }
end.
-file("/Volumes/Dev/foss/purescript-erlang-backend-test/src/Main.purs", 17).
showState() -> fun
({ state, S, I }) ->
(data_semigroup@ps:append((data_semigroup@ps:semigroupString()), <<"State ("/utf8>>, (data_semigroup@ps:append((data_semigroup@ps:semigroupString()), (data_show@ps:show((data_show@ps:showString()), S)), (data_semigroup@ps:append((data_semigroup@ps:semigroupString()), <<", "/utf8>>, (data_semigroup@ps:append((data_semigroup@ps:semigroupString()), (data_show@ps:show((data_show@ps:showInt()), I)), <<")"/utf8>>))))))))
end.
-file("/Volumes/Dev/foss/purescript-erlang-backend-test/src/Main.purs", 17).
showState(_@0) -> (fun
({ state, S, I }) ->
(data_semigroup@ps:append((data_semigroup@ps:semigroupString()), <<"State ("/utf8>>, (data_semigroup@ps:append((data_semigroup@ps:semigroupString()), (data_show@ps:show((data_show@ps:showString()), S)), (data_semigroup@ps:append((data_semigroup@ps:semigroupString()), <<", "/utf8>>, (data_semigroup@ps:append((data_semigroup@ps:semigroupString()), (data_show@ps:show((data_show@ps:showInt()), I)), <<")"/utf8>>))))))))
end(_@0)).
-file("/Volumes/Dev/foss/purescript-erlang-backend-test/src/Main.purs", 20).
handle_message() -> fun (V) ->
fun (Msg) ->
(fun
({ state, X, Y }, Msg1) ->
(fun
({ just, { reset } }) ->
{ state, <<""/utf8>>, 0 };
({ just, { add, Z } }) ->
{ state, X, Z };
({ just, { hello, N } }) ->
{ state, N, Y };
({ nothing }) ->
{ state, X, Y }
end(Msg1))
end(V, Msg))
end
end.
-file("/Volumes/Dev/foss/purescript-erlang-backend-test/src/Main.purs", 20).
handle_message(_@1,_@2) -> ((fun (V) ->
fun (Msg) ->
(fun
({ state, X, Y }, Msg1) ->
(fun
({ just, { reset } }) ->
{ state, <<""/utf8>>, 0 };
({ just, { add, Z } }) ->
{ state, X, Z };
({ just, { hello, N } }) ->
{ state, N, Y };
({ nothing }) ->
{ state, X, Y }
end(Msg1))
end(V, Msg))
end
end(_@1))(_@2)).
-file("/Volumes/Dev/foss/purescript-erlang-backend-test/src/Main.purs", 28).
loop() -> fun (State) ->
fun (Recv) ->
fun
__do() ->
((effect_class_console@ps:log((effect_class@ps:monadEffectEffect()), (data_semigroup@ps:append((data_semigroup@ps:semigroupString()), <<"current_state: "/utf8>>, (main@ps:showState(State))))))()),
Msg = ((((maps:get(receiveWithTimeout, Recv))(5000))((data_maybe@ps:'Nothing'())))()),
((main@ps:loop((main@ps:handle_message(State, Msg)), Recv))())
end
end
end.
-file("/Volumes/Dev/foss/purescript-erlang-backend-test/src/Main.purs", 28).
loop(_@3,_@4) -> fun
__do() ->
((effect_class_console@ps:log((effect_class@ps:monadEffectEffect()), (data_semigroup@ps:append((data_semigroup@ps:semigroupString()), <<"current_state: "/utf8>>, (main@ps:showState(_@3))))))()),
Msg = ((((maps:get(receiveWithTimeout, _@4))(5000))((data_maybe@ps:'Nothing'())))()),
((main@ps:loop((main@ps:handle_message(_@3, Msg)), _@4))())
end.
-file("/Volumes/Dev/foss/purescript-erlang-backend-test/src/Main.purs", 34).
main() -> fun
__do() ->
P = ((fun erl_process@ps:spawn/1(((main@ps:loop())({ state, <<"hi"/utf8>>, 0 }))))()),
((erl_process@ps:send(P, { just, { hello, <<"joe"/utf8>> } }))())
end.
% Source code generated with Caramel.
-module(holder_annotated).
-export_type([msg/0]).
-export_type([state/0]).
-export([do_work/0]).
-export([handle_message/2]).
-export([loop/2]).
-export([start/1]).
-type msg() :: reset
| {add, integer()}
| {hello, binary()}
.
-type state() :: {binary(), integer()}.
-spec handle_message(state(), option:t(msg())) -> state().
handle_message(State, Msg) ->
{X, Y} = State,
case Msg of
{some, reset} -> {<<"">>, 0};
{some, {add, Z}} -> {X, Z};
{some, {hello, N}} -> {N, Y};
none -> State
end.
-spec loop(fun((process:after_time()) -> option:t(msg())), state()) -> ok.
loop(Recv, State) ->
io:format(<<"current_state: ~p\n">>, [State | []]),
Msg = Recv({bounded, 5000}),
State2 = handle_message(State, Msg),
loop(Recv, State2).
-spec start(state()) -> erlang:pid(msg()).
start(X) -> process:make(fun
(_self, Recv) -> loop(Recv, X)
end).
-spec do_work() -> ok.
do_work() ->
Pid = start({<<"hi">>, 0}),
erlang:send(Pid, {hello, <<"joe">>}).
type msg = [ `Reset | `Add of int | `Hello of string ]
type state = string * int
let handle_message : state -> msg option -> state =
fun state msg ->
let x, y = state in
match msg with
| Some `Reset -> ("", 0)
| Some (`Add z) -> (x, z)
| Some (`Hello n) -> (n, y)
| None -> state
let rec loop ~recv state =
Io.format "current_state: ~p\n" [ state ];
let msg = recv ~timeout:(Process.Bounded 5000) in
let state2 = handle_message state msg in
loop ~recv state2
let start x = Process.make (fun _self recv -> loop ~recv x)
let do_work () =
let pid = start ("hi", 0) in
Erlang.send pid (`Hello "joe")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment