Elixir 检查功能头是否有匹配的图案?

Elixir 检查功能头是否有匹配的图案?,elixir,Elixir,假设我的函数直接在头部进行模式匹配,有没有一种方法可以让我在不调用函数的情况下检查函数是否具有与给定输入匹配的模式?有点像匹配?但用于函数。当时,我不关心,我只匹配原子或元组中的原子 e、 g 及 我正在修改GenServer中的状态,使用一系列函数来处理一些输入,而忽略其他输入。每个函数接受一个元组和一些状态,如果函数头匹配,则返回修改后的状态;如果不匹配,则返回状态。我现在有一个try/rescue包装器函数,它并不漂亮。输入是可变长度元组,第一个元素是原子标识符 严格地说,这是不可能的。只

假设我的函数直接在头部进行模式匹配,有没有一种方法可以让我在不调用函数的情况下检查函数是否具有与给定输入匹配的模式?有点像
匹配?
但用于函数。当时,我不关心
,我只匹配原子或元组中的原子

e、 g


我正在修改GenServer中的状态,使用一系列函数来处理一些输入,而忽略其他输入。每个函数接受一个元组和一些状态,如果函数头匹配,则返回修改后的状态;如果不匹配,则返回状态。我现在有一个try/rescue包装器函数,它并不漂亮。输入是可变长度元组,第一个元素是原子标识符

严格地说,这是不可能的。只是底层的包装器

检查是动态进行的,可以检查任何特定的条款,但没有准备检查的条款列表。最好的例子是一只贪婪的猫,坐在你面前;你可以试着用苹果、胡萝卜甚至回形针喂她,但除非你试过,否则你就不能说她会不会吃

另一方面,人们总是有一个查询的选项。它以算术形式响应,因此可以检测并拒绝所有
Elixir.UndefinedFunctionError
s

但子句匹配是在运行时完成的,因此无法接收允许的子句列表。考虑到子句可能是一个繁琐的警卫纠缠(<代码> ,)显式参数(<代码>:OK < /代码>),它们甚至可能重叠。


问题如其所述:

check(&init/1, :ok)  # return true
check(&init/1, :other)  # return false
但有一个强力的解决方案。我不推荐它,但它仍然可用:在调用函数时执行
check
,并从
Elixir.FunctionClauseError
中救援


另外,请不要分享我是提出这个建议的人。

你想用这个来实现什么?如果再多了解一些情况,我们可能会为您的问题提供更直接的解决方案。@PatrickOscity已更新。请随意询问是否仍不清楚。@Filiphalund不执行函数就无法检查函数头是否匹配,但我认为有几种方法可以通过现有工具实现相同的目标。你能展示更多你的代码吗?我很难理解你想做什么:|考虑到我的答案被否决了,我想我也错过了你要问的问题。我认为您需要某种case语句——这通常是我在函数中进行模式匹配的方式。但我想我遗漏了一些东西。@onriocatenacci我不想在函数中进行模式匹配,但要检查
definit(:ok)
是否会在函数头的某个已知输入上引发
FunctionClauseError
。我想知道我的哪些函数可以在不执行它们的情况下处理这个输入。你的暴力解决方案就是我目前使用的,但我不同意在一般情况下不可能。我可以编写一个宏,将第一个参数提取到function子句中,并使用
match?
或反对它的案例。我只是想要一个更地道的解决方案,而不是那么神奇。这里没有停止的问题,“我可以编写一个宏来提取函数子句的第一个参数”-除非您有复杂的保护。这是一个关于什么是子句匹配的非常有限和人为的例子,这个实现将在合法的长生不老药子句上失败。我的观点是“这在一般情况下是不可能的,这就是为什么它不能通过标准的长生不老药功能来实现。”但我没有这么严格的限制。我知道您有一个非常具体的用例。该语言本身支持通用用例。一般来说,子句匹配是不可逆的,我刚才解释了原因。更重要的是,这种方法完全违背了erlang/elixir的范式:“fail fast”意味着您的代码应该在没有匹配的情况下失败;这是预期的行为。出于某种原因,您希望提前处理这些问题,好吧,但是为什么希望语言会有所帮助呢?我认为提取所有
def
参数的宏在提取保护时不会有任何问题——它的实现比仅提取第一个参数要复杂一些。为什么你认为这“一般来说是不可能的”?
check(&init/1, :ok)  # return true
check(&init/1, :other)  # return false
check(&init/1, :ok)  # return true
check(&init/1, :other)  # return false