【发布时间】:2018-10-08 18:04:57
【问题描述】:
Maybe a 类型表示可能失败的计算,其语义我们并不关心它究竟是如何失败的。如果计算成功,则可能返回 a 类型的任何值。
反之亦然,计算可能由于多种原因而失败(我们希望保留该信息),但成功不涉及除“是的,它成功了”以外的任何信息?我可以想到两种对这种计算进行编码的明显方法:
-
Maybe e,其中Just e代表失败,Nothing代表成功。这与Maybe的通常用法大相径庭,以至于我不愿意使用它。 -
Either e (),其中Left e代表失败,Right ()代表成功。这具有显式的优点,但具有……显式的缺点。写()感觉很尴尬,尤其是在类型签名的上下文之外。
Haskell 是否有更惯用的方式来表示“多个失败案例但只有一个成功案例”?
【问题讨论】:
-
您正在寻找某种称为
Result的代数数据类型,由data Result = Ok | Error String之类的东西定义。您可以更高级地使用类型变量来处理不同类型的错误,甚至可以在Ok部分添加内容。 Elm 内置了这种类型。Haskell 有吗?它可能,环顾四周。 :) -
嗯,使用
Either e ()并创建模式同义词pattern Success = Right ()怎么样? -
如果您正在使用单子计算,那么
ExceptT err m ()将是我的第一直觉 - 一个操作成功但没有结果(成功)或产生错误。 -
除了“是的,它成功了”之外不返回任何信息的计算在 IO 操作之外听起来不是很有用,据我所知,表示错误的最惯用方式这种情况是有例外的,不是吗?老实说,这真的取决于函数的作用。
-
System.Exit定义了data ExitCode = ExitSuccess | ExitFailure Int,这基本上是 Ray Toal 的Result建议的特定于退出状态的版本。ExitCode也有一个Exception实例,这意味着要做的“标准”事情是定义自己的域特定类型。