Jimmy Hoffa
Jimmy Hoffa

Reputation: 5967

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]

Upvotes: 7

Views: 2101

Answers (3)

Fran&#231;ois
Fran&#231;ois

Reputation: 11

% 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

Upvotes: 1

rvirding
rvirding

Reputation: 20916

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])

Upvotes: 4

Satvik
Satvik

Reputation: 11208

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

Upvotes: 10

Related Questions