首页 > 解决方案 > 嵌套函数定义

问题描述

我只是在通过 Programming Elixir 和 imlpementing Split 工作。

我的代码如下 -

defmodule MyEnum do
    def split(l, n) do
        def split_helper([], pre, _n), do: {pre, []}
        def split_helper(l, pre, 0), do: {pre, l}
        def split_helper([h|t], pre, n), do: split_helper(t, [h|pre], n-1)
        split_helper(l, [], n)
    end
end

我收到错误消息 - 无法在函数/宏中调用 def/2

我的意思是我不能嵌套命名函数。由于您不能编写递归匿名函数并且没有letrec,我想知道如何在嵌套函数递归的地方嵌套函数。这就是我在球拍中构建我的代码的方式,因为我永远不需要在其他任何地方使用 split_helper。

标签: elixir

解决方案


Elixir中的函数不能嵌套。时期。

实现这一点的惯用方法是拥有一个名为do_split/3.

defmodule MyEnum do
  def split(l, n), do: do_split(l, [], n)

  defp do_split([], pre, _n), do: {pre, []}
  defp do_split(l, pre, 0), do: {pre, l}
  defp do_split([h|t], pre, n), do: do_split(t, [h|pre], n-1)
end

解决这个问题的另一种方法是简单地拥有几个子句split/3

defmodule MyEnum do
  def split(l, acc \\ [], n) # default values

  def split([], pre, _n), do: {pre, []}
  def split(l, pre, 0), do: {pre, l}
  def split([h|t], pre, n), do: split(t, [h|pre], n-1)
end

最不优雅但仍然有效的方法是创建匿名函数并将其传递给.

defmodule MyEnum do
  def split(l, n) do
    split_helper = fn
      [], pre, _, _ -> {pre, []}
      l, pre, 0, _ ->  {pre, l}
      [h|t], pre, n, split_helper ->
        split_helper.(t, [h|pre], n-1, split_helper)
    end
    split_helper.(l, [], n, split_helper)
  end
end

推荐阅读