如何在 Elixir 中编写 Monadic 值?
How To Code A Monadic Value In Elixir?
所以我试图更好地理解 monad 的概念。我试图从简单开始;那就是构建一个非常简单的 Elixir 模块,只有一个 return 函数。这个:
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>
我确定我遗漏了一些明显的东西——但我在这里遗漏了什么?
monad 是一种描述操作如何链接在一起的方式。
monad 最常见的形式是将一个函数的输出传递到链中的下一个函数。 Elixir 为此提供了管道运算符 |>
。然而:
基于 OP,不想改变元数:
传递给命名函数的原始参数从未被使用。如果你想保持命名函数的元数,但希望匿名函数返回值"chained",你可以这样实现非匿名函数:
defmodule MonadTest do
def return(s), do: fn -> s end
end
f = MonadTest.return(1)
f.()
或者,您可以像在 post:
中那样匿名使用该函数
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, &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)
所以我试图更好地理解 monad 的概念。我试图从简单开始;那就是构建一个非常简单的 Elixir 模块,只有一个 return 函数。这个:
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>
我确定我遗漏了一些明显的东西——但我在这里遗漏了什么?
monad 是一种描述操作如何链接在一起的方式。
monad 最常见的形式是将一个函数的输出传递到链中的下一个函数。 Elixir 为此提供了管道运算符 |>
。然而:
基于 OP,不想改变元数:
传递给命名函数的原始参数从未被使用。如果你想保持命名函数的元数,但希望匿名函数返回值"chained",你可以这样实现非匿名函数:
defmodule MonadTest do
def return(s), do: fn -> s end
end
f = MonadTest.return(1)
f.()
或者,您可以像在 post:
中那样匿名使用该函数 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, &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)