Haskell 中的 EAFP
EAFP in Haskell
我怀疑 Maybe 和 Either 类型,以及它们与 EAFP(更容易请求宽恕许可)的假设关系。我曾使用 Python 并习惯于在异常世界中使用 EAFP 范例。
经典例子:除以零
def func(x,y):
if not y:
print "ERROR."
else: return (x/y)
和Python的风格:
def func(x,y):
try:
return (x/y)
except: return None
在Haskell中,第一个函数是
func :: (Eq a, Fractional a) => a -> a -> a
func x y = if y==0 then error "ERROR." else x/y
与 Maybe:
func :: (Eq a, Fractional a) => a -> a -> Maybe a
func x y = if y==0 then Nothing else Just (x/y)
在 Python 的版本中,您 运行 func
没有 检查 y
。对于 Haskell,情况正好相反:y
被选中。
我的问题:
- 形式上,Haskell 是否支持 EAFP 范式或 "prefers" LBYL 尽管承认半奇怪的 EAFP 近似?
PD:我打电话给 "semi-bizarre" 是因为,即使它直观可读,它看起来(至少对我而言)就像它会破坏 EAFP。
带有 Maybe
和 Either
的 Haskell 样式强制您在 某个点 检查错误,但它没有马上。如果您现在不想处理错误,您可以将其传播到其余的计算中。
以您假设的安全除以 0 为例,您可以在更广泛的计算中使用它而无需显式检查:
do result <- func a b
let x = result * 10
return x
在这里,您不必匹配 func
返回的 Maybe
:您只需使用 do-notation 将其提取到 result
变量中,它会自动传播失败始终。结果是您不需要立即处理潜在的错误,但计算的最终结果包含在 Maybe
本身中。
这意味着您可以轻松组合(组合)可能导致错误的函数,而无需在每一步检查错误。
从某种意义上说,这可以让您两全其美。你仍然只需要在最后检查一个地方的错误,但你明确。您必须使用诸如 do-notation 之类的东西来处理实际的传播,并且您不能意外地忽略最终错误:如果您不想处理它,则必须明确地将其转换为运行时错误。
显式不是比隐式好吗?
现在,Haskell 也有一个异常系统,用于处理您根本不必检查的运行时错误。这偶尔有用,但不会太频繁。在 Haskell 中,我们仅将其用于我们 不希望 捕获的错误——真正的异常情况。经验法则是,运行时异常表示 程序中的错误 ,而不正确的输入或仅仅是不常见的情况应表示为 Maybe
或 Either
.
我怀疑 Maybe 和 Either 类型,以及它们与 EAFP(更容易请求宽恕许可)的假设关系。我曾使用 Python 并习惯于在异常世界中使用 EAFP 范例。
经典例子:除以零
def func(x,y):
if not y:
print "ERROR."
else: return (x/y)
和Python的风格:
def func(x,y):
try:
return (x/y)
except: return None
在Haskell中,第一个函数是
func :: (Eq a, Fractional a) => a -> a -> a
func x y = if y==0 then error "ERROR." else x/y
与 Maybe:
func :: (Eq a, Fractional a) => a -> a -> Maybe a
func x y = if y==0 then Nothing else Just (x/y)
在 Python 的版本中,您 运行 func
没有 检查 y
。对于 Haskell,情况正好相反:y
被选中。
我的问题:
- 形式上,Haskell 是否支持 EAFP 范式或 "prefers" LBYL 尽管承认半奇怪的 EAFP 近似?
PD:我打电话给 "semi-bizarre" 是因为,即使它直观可读,它看起来(至少对我而言)就像它会破坏 EAFP。
带有 Maybe
和 Either
的 Haskell 样式强制您在 某个点 检查错误,但它没有马上。如果您现在不想处理错误,您可以将其传播到其余的计算中。
以您假设的安全除以 0 为例,您可以在更广泛的计算中使用它而无需显式检查:
do result <- func a b
let x = result * 10
return x
在这里,您不必匹配 func
返回的 Maybe
:您只需使用 do-notation 将其提取到 result
变量中,它会自动传播失败始终。结果是您不需要立即处理潜在的错误,但计算的最终结果包含在 Maybe
本身中。
这意味着您可以轻松组合(组合)可能导致错误的函数,而无需在每一步检查错误。
从某种意义上说,这可以让您两全其美。你仍然只需要在最后检查一个地方的错误,但你明确。您必须使用诸如 do-notation 之类的东西来处理实际的传播,并且您不能意外地忽略最终错误:如果您不想处理它,则必须明确地将其转换为运行时错误。
显式不是比隐式好吗?
现在,Haskell 也有一个异常系统,用于处理您根本不必检查的运行时错误。这偶尔有用,但不会太频繁。在 Haskell 中,我们仅将其用于我们 不希望 捕获的错误——真正的异常情况。经验法则是,运行时异常表示 程序中的错误 ,而不正确的输入或仅仅是不常见的情况应表示为 Maybe
或 Either
.