Search code examples
erlangpattern-matchinganonymous-functionerlang-shell

anonymous function and pattern matching


I try to understand how to give anomous function different arguments, and what is passed on to the anonymous function as an argument. Try to do so in order to relate it to pattern matching.

I've had a look at:

https://learnyousomeerlang.com/higher-order-functions#anonymous-functions

Here it is stated that:

fun(Args1) ->
Expression1, Exp2, ..., ExpN;
(Args2) ->
Expression1, Exp2, ..., ExpN;
(Args3) ->
Expression1, Exp2, ..., ExpN
end

I guess I could just pass different arguments and get different patterns. However I've made the following code:

mkt(add, {V1, C}) -> 
  fun(new) -> {changed_value, V1, C};
    ({exst_value, V2}) ->
      try V1 + V2 of
        Res -> {changed_value, Res, C}
      catch 
        _:_ -> 
          nothing
      end
  end;

mkt(mult, {V1, C}) -> 
  fun(new) -> {changed_value, V1, C};
    ({exst_value, V2}) ->
      try V1 * V2 of
        Res -> {changed_value, Res, C}
      catch 
        _:_ -> 
          nothing
      end
  end.

sym_mkt(Opr, Args) -> {call, ?MODULE, mkt, [Opr, Args]}.

term_transf(KeyGen) ->
  oneof(
    [ ?LET({K, V, C}, {KeyGen, int(), cost()},
              return ({K, sym_mkt(add,{V,C})})),      
      ?LET({K, V, C}, {KeyGen, int(), cost()},
              return ({K, sym_mkt(mult,{V,C})}))     
      
      ]).

Based on the calls to the mkt(...) with its current variables is there a way to pass it the arguments, such that the anonymous function with the second atom ( e.g. {exst_value, ...}) is activated, because I don't see how the arguments for the mkt could ever match those.

Furthermore, what does get passed to anonymous functions as arguments in general. If I give several arguments to a function with an anonymous function in it, from what I can see, it takes the first of these arguments. But is that always the case?


Solution

  • I think the confusion lies in what is returned by mkt/2, which is not a value of the form {changed_value, Res, C}, but rather a new (anonymous) function. That function can then be given an argument matching the pattern {exst_value, V2} (or new) as evident by the following interaction in erl (where I put your definition of mkt/2 in a module called tmp):

    1> c(tmp).
    {ok,tmp}
    2> F = tmp:mkt(add, {1, foo}).
    #Fun<tmp.1.37861693>
    3> F({exst_value, 2}).
    {changed_value,3,foo}
    4> F(new).
    {changed_value,1,foo}
    

    Regarding your second question, anonymous functions can accept multiple arguments.