[erlang-questions] How to create a function using merl given a list of clauses

Svilen Ivanov isvilen@REDACTED
Wed Feb 14 20:47:45 CET 2018


On Wed, 2018-02-14 at 13:31 +0100, Frans Schneider wrote:
> Dear list,
> 
>  From a set of user defined rules, I want to create functions of the
> form:
> 
> fun([V1, V2]) ->
>      fun () when V1 < 1, is_atom(V2) -> foo();
>          () when V2 =/= b -> bar();
>          () -> false
>      end
> end.
> 
> The number of arguments, clauses and guards differ. Guards always
> are 
> ANDed or andalso should be used.
> 
> To build the internal fun I do something like:
> 
> ...
> -include_lib("syntax_tools/include/merl.hrl").
> ...
> tst() ->
>      %% This is the end result I want
>      V1 = 10,
>      V2 = a,
>      Func = ?Q(["fun () when _@REDACTED@ < 1, is_atom(_@REDACTED@) -> foo();",
>             "    () when _@REDACTED@ =/= b -> bar();",
>             "    () -> false ",
>             "end"]),
>      %% io:format("Func ~p~n", [Func]),
>      merl:print(Func),
> 
>      %% This is the data produced by some function
>      Guard1 = ?Q("_@REDACTED@ < 1"),
>      Guard2 = ?Q("is_atom(_@REDACTED@)"),
>      Guard3 = ?Q("_@REDACTED@ =/= b"),
>      GSeq1 = [Guard1, Guard2],
>      GSeq2 = [Guard3],
> 
>      %% Now start assembling the fun
>      Clause1 = ?Q("() when _@REDACTED -> foo()"),
>      Clause2 = ?Q("() when _@REDACTED -> bar()"),
>      Clauses = [Clause1, Clause2],
>      merl:print(Clauses),
> 
>      %% And this gives the error: syntax error before: 'fun'"
>      Func1 = ?Q("fun _@REDACTED end"),
>      merl:print(Func1).
> 
> I just can't figure out a way to make the last step assembling the
> fun work.
> 
> Your suggestions are highly appreciated!
> 
> Frans
> 

You should look at "lifting" in http://erlang.org/doc/man/merl.html ,
something like this seems to work:
----------------------------------------------------
-include_lib("syntax_tools/include/merl.hrl").

tst() ->
     V1 = merl:var('V1'),
     V2 = merl:var('V2'),

     Guard1 = ?Q("_@REDACTED < 1"),
     Guard2 = ?Q("is_atom(_@REDACTED)"),
     Guard3 = ?Q("_@REDACTED =/= b"),
     GSeq1 = [Guard1, Guard2],
     GSeq2 = [Guard3],

     Clause1 = ?Q("() when _@REDACTED -> foo()"),
     Clause2 = ?Q("() when _@REDACTED -> bar()"),
     Clauses = [Clause1, Clause2],

     Func1 = ?Q("fun() -> _@REDACTED@Clauses end"),

     Func2 = ?Q("fun([_@REDACTED,_@REDACTED]) -> _@REDACTED end"),

     merl:print(Func2).
------------------------------------------------------

Svilen



More information about the erlang-questions mailing list