简体   繁体   English

在Haskell中的case语句中使用默认值

[英]Using a default in a case statement in Haskell

I am trying to create a new data declaration called place. 我正在尝试创建一个名为place的新数据声明。

It looks like this: 它看起来像这样:

data place = United States | France | England | Germany | Mexico | Canada

My hope is to then use a function called cap to take the place to its capital like so: 我希望然后使用一个名为cap的函数来取代它的资本,如下所示:

cap :: place -> String
cap a = case a of

            Spain           -> "Madrid"
            France          -> "Paris"
            England         -> "London"
            Germany         -> "Berlin"
            Mexico          -> "Mexico City"
            Canada          -> "Ottawa"
            _               -> undefined

However the last case, where I am attempting to catch all other entries that may not exist in the data declaration does not work. 但是,最后一种情况,我试图捕获数据声明中可能不存在的所有其他条目不起作用。 If I enter capital Wales for instance in GHCI, I don't get an undefined response. 如果我在GHCI进入capital Wales ,我不会得到一个不明确的回应。 Instead I get a not in scope error. 相反,我得到一个不在范围内的错误。 Can someone help me with my confusion and perhaps provide a legitimate way of trying to catch other cases? 有人可以帮助我解决我的困惑,也许可以提供一种试图捕捉其他案件的合法方式吗?

The problem isn't with how you handle missing cases - how you're doing it is fine. 问题不在于你如何处理丢失的案件 - 你如何处理它是好的。 The problem is that the Wales constructor simply does not exist. 问题是Wales构造函数根本不存在。 So just like when you try to use a variable or function that has not been defined, you get a compilation error. 因此,就像当您尝试使用尚未定义的变量或函数时,您会收到编译错误。 Your cap function never even gets called, so no changes you could do to it, would affect this behaviour. 您的cap函数甚至不会被调用,因此您无法对其进行任何更改会影响此行为。 There's nothing you can do to make code that uses non-existing constructors compile. 使用不存在的构造函数编译代码是无法做到的。

When you enter capital Wales , there is no Wales in scope. 当您进入capital Wales ,范围内没有Wales It is not possible for you to construct a value that does not exist. 您无法构造不存在的值。 If you have covered every possible case, then you do not need a default case. 如果您已涵盖所有可能的案例,那么您不需要默认案例。

To riff on sepp2k's and singpolyma's answers, the point here is that Haskell's union types are exhaustive . 为了重复sepp2k和singpolyma的答案,这里的重点是Haskell的联合类型是详尽无遗的 When you define a union type with n cases, you are telling Haskell that those n cases are the only cases that exist for your type. 当你定义一个联合类型具有n个的情况下,你是在告诉哈斯克尔那些n个个案是存在你的类型的唯一案例。 As singpolyma points out, you've told Haskell that other cases don't even exist . 正如singpolyma指出的那样,你告诉Haskell,其他案例甚至都不存在

This has benefits and drawbacks. 这有利有弊。 Exhaustiveness means that you and the compiler can guarantee that your functions are handling all possible inputs that they will be given. 穷举意味着您和编译器可以保证您的函数正在处理它们将被给予的所有可能输入。 The drawback is that the set of cases is fixed at compilation time. 缺点是在编译时固定了一组案例。

The simplest alternative here is two-part: 这里最简单的选择是两部分:

  1. Use an "open" type—one for which you can create arbitrarily many different instances at runtime—to represent nations and capitals. 使用“开放”类型 - 您可以在运行时创建任意多个不同的实例 - 来表示国家和大写字母。 Strings are a good one here; 弦乐在这里很好; there is an infinite number of different strings that you can construct at runtime. 您可以在运行时构建无限数量的不同字符串。 But you can also use a record type with a string member. 但您也可以使用带有字符串成员的记录类型。
  2. Use key/value assignment data structures to represent the association between the countries and the capitals. 使用键/值分配数据结构来表示国家和首都之间的关联。

So you could represent nations and cities like this: 所以你可以像这样代表国家和城市:

-- 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

The simplest key/value mapping type is [(k, v)] , often known as an association list . 最简单的键/值映射类型是[(k, v)] ,通常称为关联列表 It has of course an O(n) lookup time. 它当然具有O(n)查找时间。 A better one is to use Data.Map , which comes with the Haskell Platform. 更好的方法是使用Haskell平台附带的Data.Map

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM