2013-04-24 121 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,所以你可以做这样的很酷的东西。