[英]Why is the default catch-all not mandatory in a Haskell case statement?
[英]Using a default in a case statement in Haskell
我正在尝试创建一个名为place的新数据声明。
它看起来像这样:
data place = United States | France | England | Germany | Mexico | Canada
我希望然后使用一个名为cap的函数来取代它的资本,如下所示:
cap :: place -> String
cap a = case a of
Spain -> "Madrid"
France -> "Paris"
England -> "London"
Germany -> "Berlin"
Mexico -> "Mexico City"
Canada -> "Ottawa"
_ -> undefined
但是,最后一种情况,我试图捕获数据声明中可能不存在的所有其他条目不起作用。 如果我在GHCI进入capital Wales
,我不会得到一个不明确的回应。 相反,我得到一个不在范围内的错误。 有人可以帮助我解决我的困惑,也许可以提供一种试图捕捉其他案件的合法方式吗?
问题不在于你如何处理丢失的案件 - 你如何处理它是好的。 问题是Wales
构造函数根本不存在。 因此,就像当您尝试使用尚未定义的变量或函数时,您会收到编译错误。 您的cap
函数甚至不会被调用,因此您无法对其进行任何更改会影响此行为。 使用不存在的构造函数编译代码是无法做到的。
当您进入capital Wales
,范围内没有Wales
。 您无法构造不存在的值。 如果您已涵盖所有可能的案例,那么您不需要默认案例。
为了重复sepp2k和singpolyma的答案,这里的重点是Haskell的联合类型是详尽无遗的 。 当你定义一个联合类型具有n个的情况下,你是在告诉哈斯克尔那些n个个案是存在你的类型的唯一案例。 正如singpolyma指出的那样,你告诉Haskell,其他案例甚至都不存在 。
这有利有弊。 穷举意味着您和编译器可以保证您的函数正在处理它们将被给予的所有可能输入。 缺点是在编译时固定了一组案例。
这里最简单的选择是两部分:
所以你可以像这样代表国家和城市:
-- Since there are infinitely many different strings you could construct at runtime,
-- there are also infinitely many different Cities and Nations...
data City = City String deriving (Eq, Ord, Show)
data Nation = Nation String deriving (Eq, Ord, Show
最简单的键/值映射类型是[(k, v)]
,通常称为关联列表 。 它当然具有O(n)查找时间。 更好的方法是使用Haskell平台附带的Data.Map
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.