2013-04-24 7 views
7

Ich versuche, alle meine Haskell Hausaufgaben Probleme mit Erlang wiederholen, und eine Sache, die mich bekommt, ist, wie man eine Liste von Funktionen, die nicht alle ihre Parameter haben.Currying Funktionen Erlang

Beispiel: Ich versuche, diese Falte zu verwenden, aber ich weiß nicht, wie in den Funktionen übergeben, so dass sie auf dem Speicher arbeiten

%%inside my module) 
add(X,Y) -> X + Y. 

multiply(X,Y) -> X*Y. 

mit dieser anschließend in der Befehlszeile:

lists:foldl(fun(Function,Accumulator) -> Function(Accumulator) end, 3, [add(3),multiply(5)]). 

Antwort

9

In Erlang müssen Sie Funktion aufrufen, alle Parameter übergeben es erfordert. Sie können dies jedoch leicht vermeiden, indem Sie eine anonyme Funktion erstellen, die nur die Parameter verwendet, die Sie benötigen, und dann Ihre Funktion richtig aufruft. Wenn Sie eine Funktion benötigen, die X einen Parameter und ruft Funktion add (3, X) können Sie eine anonyme Funktion wie das erstellen:

fun (X) -> add(3, X) end 

Dies ist ein Beispiel für Ihre Aufgabe:

lists:foldl(fun (Function, Accumulator) -> Function(Accumulator) end, 3, 
    [fun (X) -> add(3, X) end, fun (X) -> multiply(5, X) end]). 
0
lists:foldl(
    fun(Function,Accumulator) -> Function(Accumulator) end, 
    3, 
    [ 
     fun(X) -> modname:add(3, X) end, 
     fun(X) -> modname:multiply(5, X) end 
    ] 
). 
+0

Dies bedeutet, dass es in Erlang keine Teilfunktionsanwendung gibt (und kein Currying), oder? Weil Sie von Lambda-Funktionen Gebrauch machen, während wir in Haskell eine Liste von partiell applizierten (?) Funktionen haben könnten: '[(+) 1, (-) 2, (*) 3]'. Oder ist es immer noch das gleiche wie Teilfunktionsanwendung? – ichistmeinname

1

Man kann ziemlich leicht eine partielle Anwendungsfunktion schreiben, die analog zu erlang heißt: apply/3. Es fehlt die Eleganz, die Sie in Sprachen haben, die Curry unterstützen.

-module(partial). 

-export([apply/4]). 

apply(Module, Name, Arity, Args) when length(Args) < Arity -> 
    Left = Arity - length(Args), 
    fun(Args1) when length(Args1) < Left -> 
      fun(Args2) -> 
       apply(Module, Name, Arity, Args2 ++ Args1 ++ Args) 
      end; 
     (Args1) when length(Args1) > Left -> 
      erlang:error(badarg); 
     (Args1) -> 
      erlang:apply(Module, Name, Args1 ++ Args) 
    end; 
apply(_, _, Arity, Args) when length(Args) > Arity -> 
    erlang:error(badarg); 
apply(Module, Name, _, Args) -> 
    erlang:apply(Module, Name, Args). 
3

In Bezug auf native Erlang gibt es keine Form der Teilbewertung wie Sie wollen. Sie müssen Ihre eigenen Spaß machen, um es zu tun. Wenn Sie jedoch die Erlando Monad Library verwenden, können Sie die Mustererkennung verwenden, um sie zu erstellen. Es funktioniert durch die Tatsache, dass der Erlang-Compiler Sie mit dem AST beim Kompilieren von Code spielen lässt, so dass Sie coole Sachen wie diese machen können.