2013-04-24 22 views
7

Erlang'ı kullanarak tüm Haskell ev ödevi sorunlarını yeniden çözmeye çalışıyorum ve beni etkileyen bir şey, tüm parametrelerine sahip olmayan işlevlerin listesini kullanmaktır.Curering Functions Erlang

Örnek: Bu kat kullanmaya çalışıyorum, ancak komut satırında bu kullanarak akümülatör Daha sonra

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

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

çalışır böylece işlevleri geçmesine nasıl bilmiyorum:

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

cevap

9

Erlang ise bunu gerektirir tüm parametreleri geçen işlevini çağırmalıdır. Ancak, sadece ihtiyacınız olan parametreleri alan ve daha sonra işlevinizi doğru olarak çağıran anonim bir işlev oluşturarak kolayca önleyebilirsiniz.

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

Bu, Erlang'da kısmi işlev uygulamasının olmadığı anlamına gelir (ve köreltmez), değil mi? Çünkü lambda-fonksiyonlarından yararlanırsınız, oysa Haskell'de kısmi uygulamalı (?) Fonksiyonların bir listesini yapabiliriz: '[(+) 1, (-) 2, (*) 3]'. Yoksa hala kısmi işlev uygulamasıyla aynı mı? – ichistmeinname

1

: Bu görev için bir örnektir

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

: Eğer işlev eklenti bir parametre X alır ve çağıran bir işlev gerekiyorsa (3 X) Böyle bir anonim işlev oluşturabilir Bir kişi, erlang için benzer bir yol olarak adlandırılan kısmi bir uygulama fonksiyonunu kolayca yazabilir: apply/3. Körlenmeyi destekleyen dillerde sahip olduğunuz zarafetten yoksun.

-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

Yerel Erlang açısından, istediğiniz gibi herhangi bir kısmi değerlendirme türü yoktur. Bunu yapmak için kendi eğlencenizi yaratmanız gerekecek. Ancak, Erlando Monad Library'u kullanırsanız, oluşturmak için desen eşleştirmeyi kullanabilirsiniz. Erlang derleyicisi, derleme kodunda AST ile oynamanıza izin veriyor, böylelikle bunun gibi güzel şeyler yapabilirsiniz.