Erlang 案例表达式中防护失败时的长生不老药行为

Erlang 案例表达式中防护失败时的长生不老药行为,erlang,elixir,Erlang,Elixir,为什么case在保护失败时不抛出运行时异常,而是静默失败,从而隐藏潜在的bug 比如为什么 case [] do xs when hd(xs) -> "Won't match" xs -> "Got #{xs}" end 由于hd(xs)失败,不返回参数错误 更新:我提出这个问题是因为哈斯凯尔的守卫不会出现同样的情况。例如,函数 myfun x | head([]) == x = 100 | otherwise = 200 在GHCi中调用时生成 λ>

为什么
case
在保护失败时不抛出运行时异常,而是静默失败,从而隐藏潜在的bug

比如为什么

case [] do
   xs when hd(xs) -> "Won't match"
   xs -> "Got #{xs}"
end
由于
hd(xs)
失败,不返回参数错误

更新:我提出这个问题是因为哈斯凯尔的守卫不会出现同样的情况。例如,函数

myfun x
  | head([]) == x = 100
  | otherwise = 200
在GHCi中调用时生成

λ> myfun 6
*** Exception: Prelude.head: empty list
简而言之,与Haskell不同,Haskell不向程序员隐藏异常,Elixir在守卫中吃掉异常的行为背后的设计原理是什么


谢谢,

由保护函数引发的任何错误都将被默认忽略,匹配将被视为不成功。该文件记录在:

如果算术表达式、布尔表达式、短路表达式或对保护BIF的调用失败(因为参数无效),则整个保护将失败。如果防护是防护序列的一部分,则会计算序列中的下一个防护(即,下一个分号后面的防护)


因为这是警卫的工作方式。如果它提出,这个案件将永远不会成为一个案件。如果要引发异常,请使用直接模式匹配。@mudasobwa充当
案例是什么意思?对我来说,在程序中伪装错误的东西是语言中的一个设计缺陷。根据你的逻辑,所有允许拯救异常的语言都有一个设计流程。它没有伪装任何东西。它显式捕获任何可能的异常并返回
false
。这使得守卫更加简洁,这是完美的。这是一个守卫,不是一个随机的代码。事实上,对你来说,它似乎是一个设计流,与设计流没有任何关系。@mudasobwa不,不,这不是一个明确的捕获,而是一个隐含的捕获。如果你的程序在一个守卫之外访问一个空列表的头,而语言会为你抛出一个运行时异常,那么你就不会考虑一个bug吗?或者你更愿意在这种情况下得到零分,然后继续前进?如果长生不老药在守卫外抛出异常,它在守卫内的行为应该与此一致。“守卫内的行为应该与此一致”-哦,真的吗?为什么呢?因为您不熟悉
警卫
?正如文档中所明确指出的那样,guard的捕获是一种明确的捕获。这是一个合同:
rescue
guard
都是明确的捕获。我的问题不是它是如何工作的,而是它为什么这样工作。对我来说,这似乎是一个设计缺陷,给了程序员一个让他们的bug被默默忽略的机会。这种行为在语言中有什么强烈的原因吗?