From 3250a38411e2f1a024be19c3a7b6361f59cb9976 Mon Sep 17 00:00:00 2001 From: Matthew Sackman Date: Sun, 3 Apr 2011 23:50:31 +0100 Subject: [PATCH] Implement a couple of other standard monad helpers --- src/monad.erl | 20 ++++++++++++++++++++ test/src/test_do.erl | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/src/monad.erl b/src/monad.erl index d3417f7..1ca40e9 100644 --- a/src/monad.erl +++ b/src/monad.erl @@ -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}, @@ -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). diff --git a/test/src/test_do.erl b/test/src/test_do.erl index 03714c8..11a8536 100644 --- a/test/src/test_do.erl +++ b/test/src/test_do.erl @@ -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).