使用 Elixir 的优势是什么 "with"

What is the advantage of using Elixir's "with"

I saw this code at the Elixir School:

with {:ok, user} <- Repo.insert(changeset),
     {:ok, token, full_claims} <- Guardian.encode_and_sign(user, :token, claims) do
  important_stuff(token, full_claims)
end

我不明白简单的区别:

{:ok, user} <- Repo.insert(changeset),
{:ok, token, full_claims} <- Guardian.encode_and_sign(user, :token, claims)
important_stuff(token, full_claims)

{:ok, user} <- Repo.insert(changeset) 没有 with 会首先提高 (CompileError) undefined function <-/2。你的意思可能是 {:ok, user} = Repo.insert(changeset).

Kernel.SpecialForms.with/1在某种程度上起到了任一monad的作用。

如果RHO匹配到LHO,则进入下一个子句。否则,它立即 returns 非匹配的 RHO,丢弃所有其他子句。考虑几个应该按顺序应用的函数,如果前一个函数成功的话。有点像这样。

with {:ok, text} <- File.read(name),
     {:ok, words} <- MyStemmer.get_words(text),
     count when in_integer(count) <- Enum.count(words),
  do: IO.puts("File contained #{count}" words)

如果没有这样的文件,整个片段将 return {:error, :enoent} 因为第一个子句无法匹配 LHO.

当没有这样的文件时,

{:ok, text} = File.read(name) 会引发 MatchError


三年前我写过一篇blog post,可能还是值得一读。