Skip to content

Instantly share code, notes, and snippets.

@msackman
Created March 30, 2011 16:15
Show Gist options
  • Save msackman/894702 to your computer and use it in GitHub Desktop.
Save msackman/894702 to your computer and use it in GitHub Desktop.
-module(test_do).
-compile({parse_transform, erlando}).
-compile(export_all).
test_statet(Arg) ->
StateT = statet:new(maybe), %% statet wrapping of maybe monad
StateT:execStateT(
do([StateT
|| S0 <- StateT:get(),
return(io:format("~p~n",[S0])),
StateT:put(some_new_state),
return(wibble)
]), Arg).
-module(statet, [InnerMonad]). %% Yes, use a parameterised module
-compile({parse_transform, erlando}).
-compile(export_all).
'>>='(X, Fun) -> fun (S) -> do([InnerMonad || {A, S1} <- X(S),
(Fun(A))(S1)]) end.
'>>'(X, Fun) -> fun (S) -> do([InnerMonad || {_A, S1} <- X(S),
(Fun())(S1)]) end.
return(A) -> fun (S) -> InnerMonad:return({A, S}) end.
fail(Str) -> fun (_) -> InnerMonad:fail(Str) end.
get() -> fun (S) -> InnerMonad:return({S, S}) end.
put(S) -> fun (_S) -> InnerMonad:return({ok, S}) end.
evalStateT(Monad, S) -> do([InnerMonad || {A, _S1} <- Monad(S),
return(A)]).
execStateT(Monad, S) -> do([InnerMonad || {_A, S1} <- Monad(S),
return(S1)]).
After parse transform of test_do:
test_statet(Arg) ->
StateT = statet:new(maybe),
StateT:execStateT(StateT:'>>='(StateT:get(),
fun (S0) ->
StateT:'>>'(StateT:return(io:format("~p~n",
[S0])),
fun () ->
StateT:'>>'(StateT:put(some_new_state),
fun
() ->
StateT:return(wibble)
end)
end)
end),
Arg).
Then running:
1> test_do:test_statet(the_old_state).
the_old_state
{just,some_new_state}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment