所以我试图更好地理解monad的想法。我试着开始简单;这是一个非常简单的Elixir模块,只有一个返回功能。这样:
defmodule MonadTest do
def return(s), do: fn s -> s end
end
然后我以这种方式将函数绑定到变量:
f = &MonadTest.return/1
然后我尝试这样调用函数:
f.(12)
但是我没有回到12,而是获得了这个功能。像这样:
iex(22)> r = f.(12)
#Function<0.122071921/1 in MonadTest.return/1>
iex(23)> r
#Function<0.122071921/1 in MonadTest.return/1>
我确定我错过了一些明显的东西 - 但我在这里错过了什么?
答案 0 :(得分:7)
monad是一种描述如何将操作链接在一起的方式。
monad最常见的形式是将输出从一个函数传递到链中的下一个函数。 Elixir为此提供管道操作员|>
。但是:
基于OP,不想改变arity:
永远不会使用传递给指定函数的原始参数。如果你想维护命名函数的arity,但希望匿名函数“chained”返回值,你可以实现非匿名函数:
defmodule MonadTest do
def return(s), do: fn -> s end
end
f = MonadTest.return(1)
f.()
或者,您可以像在帖子中那样匿名使用该功能:
defmodule MonadTest do
def return(s), do: fn -> s end
end
f = &MonadTest.return/1
f.(1).()
我认为这里有两件事我们可以澄清。 (1)是&<NamedFunction>/<arity>
语法,第二个是参数的传递方式。
语法&MonadTest.return/1
将生成一个匿名函数,其具有与命名函数MonadTest.return
相同的定义。
这通常在将命名函数作为参数传递时使用,例如,如果需要在可枚举方法中使用MonadTest.return / 1,例如Enum.map(1..5,&amp; MonadTest.return / 1) )。
在我的例子中,我不打算将参数传递给命名函数,因为你将它传递给新定义的MonadTest.return / 0中的匿名函数。
出于您的目的,您可能不需要生成匿名函数,而是可以直接引用命名函数:
defmodule MonadTest do
def return, do: fn s -> s end
end
f = MonadTest.return
f.(12)
如果你确实需要MonadTest是匿名的,你需要调用它,然后将参数传递给嵌套在其中的匿名函数。
defmodule MonadTest do
def return, do: fn s -> s end
end
f = &MonadTest.return/0
f.().(12)