简体   繁体   中英

Erlang equivalents of Haskell where/partial/lambda

Coming from Haskell to play with Nitrogen and running into a few things I can't find examples of, so if somebody could help me out:

Haskell's where (and or let or any type of function nesting with access to parent variables) in erlang? How? Can you?

burnOrDie hotness = foldl1 (>>) $ map burn ["Jimmy", "Adam", "Gonzo"]
  where burn x
          | hotness < 3 = print $ x ++ ": Ouch!"
          | otherwise = print $ x ++ ": GAHHH! *die*"

Partial application? Haskell: addOne = +1

in-line lambda function? Haskell: map (\\x -> x+x) [1,2,3]

I am no expert in erlang but I will try to answer.

Nesting functions

out(A) ->
    X = A + 1,
    SQ = fun(C) -> C*C end,
    io:format("~p",[SQ(X)]).

here SQ function has access to parent variables.

In Lambda

This is same as above, you can use fun to define your anonymous functions.

Partial application

I don't think erlang has partial function application in any sane way. The only thing you can do is to wrap functions to return function.

add(X) -> 
    Add2 = fun(Y) -> X + Y end,
    Add2.

Now you can do something like

1> c(test).
{ok,test}
2> A=test:add(1).
#Fun<test.0.41627352>
3> A(2).
3

Erlang doesn't have nested functions in the sense that Haskell and other languages do. When @Satvik created a function using SQ = fun(C) -> C*C end he was creating a closure, or fun in Erlang, and not a nested function. The syntax fun (...) -> ... end creates a fun or closure. which is not really the same thing.

Partial evaluation as in Haskell does not exist in Erlang, though you can hack it using funs.

You define in-line lambdas (funs) with the fun syntax. So you map becomes:

lists:map(fun (X) -> X+X end, [1,2,3])
% partially evaluating a function of two arguments
partial_eval(F, X, Pos) -> case Pos of
                              1 -> fun(Y) -> F(X,Y) end;
                              2 -> fun(Y) -> F(Y,X) end
                            end.

partial_eval(F,X) -> partial_eval(F,X,1). 

With the above code in a module named test.erl , at the console:

7> c(test).
{ok,test}
8> Sum = fun(X,Y) -> X + Y end.
#Fun<erl_eval.13.126501267>
9> PS = test:partial_eval(Sum,3).
#Fun<test.1.126208848>
10> PS(4).
7
11> (test:partial_eval(Sum,3))(4). % can be invoked directly too
7
12> Div = fun(X,Y) -> X/Y end.
#Fun<erl_eval.13.126501267>
13> (test:partial_eval(Div,27))(3).
9.0
14> (test:partial_eval(Div,10,2))(3). % partial evaluation of second parameter
0.3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM