Skip to content
This repository has been archived by the owner on Aug 30, 2019. It is now read-only.

Commit

Permalink
Implement a couple of other standard monad helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthew Sackman committed Apr 3, 2011
1 parent f115d3e commit 3250a38
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/monad.erl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@
-module(monad).

-export([behaviour_info/1]).
-export([join/2, sequence/2]).

-ifdef(use_specs).
-type(monad(_A) :: any()). %% urm, don't know what to do here.
-spec(join/2 :: (atom(), monad(monad(A))) -> monad(A)).
-spec(sequence/2 :: (atom(), [monad(A)]) -> monad([A])).
-endif.

-compile({parse_transform, erlando}).

behaviour_info(callbacks) ->
[{'>>=', 2},
Expand All @@ -25,3 +34,14 @@ behaviour_info(callbacks) ->
{fail, 1}];
behaviour_info(_Other) ->
undefined.

join(Monad, X) ->
do([Monad || Y <- X(),
Y()]).

sequence(Monad, Xs) ->
lists:foldr(fun (X, Acc) ->
do([Monad || E <- X,
Es <- Acc,
return([E|Es])])
end, Monad:return([]), Xs).
5 changes: 5 additions & 0 deletions test/src/test_do.erl
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,8 @@ test_omega() ->
return({X,Y,Z})]),
true = A =/= B,
true = A =:= lists:usort(B).

test_sequence() ->
List = lists:seq(1,5),
ListM = [do([maybe_m || return(N)]) || N <- List],
{just, List} = monad:sequence(maybe_m, ListM).

0 comments on commit 3250a38

Please sign in to comment.