2013-04-24 125 views
7

我想重做所有使用Erlang的Haskell作業問題,而有一件事情讓我知道如何使用沒有所有參數的函數列表。柯里函數Erlang

例子:我試圖用這個折,但我不知道如何在功能通過,使得它在命令行中使用該蓄電池

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

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

然後運行:

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

回答

9

在Erlang中,你必須調用函數傳遞它需要的所有參數。但是你可以通過創建一個匿名函數來輕鬆避免它,它只需要你需要的那些參數,然後正確地調用你的函數。如果你需要一個函數,它接受一個參數X,調用函數add(3,X),可以創建這樣一個匿名函數:

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

這是你的任務的例子:

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

這意味着在Erlang中沒有部分函數應用程序(也沒有currying),對吧?因爲您使用了lambda函數,而在Haskell中,我們可以使用部分應用函數(?)的列表: '[(+)1,( - )2,(*)3]'。還是它仍然與部分功能應用程序一樣? – ichistmeinname 2013-04-24 06:12:03

1

人們可以很容易地編寫一個稱爲erlang的類似方法的部分應用程序函數:apply/3。它缺乏支持柯式語言的優雅。

-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

就本地Erlang而言,沒有任何形式的部分評估就像你想要的。你將不得不創造你自己的樂趣來做到這一點。但是,如果您使用Erlando Monad Library,那麼您可以使用模式匹配來創建它。它的工作原理是erlang編譯器可以讓你在編譯代碼時玩AST,所以你可以做這樣的很酷的東西。