简体   繁体   English

如何使用 Haskell 中的数据构造函数?

[英]How can I work with the data constructors in Haskell?

I have a problem with working with data constructors and would be happy if someone could help.我在使用数据构造函数时遇到问题,如果有人能提供帮助,我会很高兴。 So I have a data type Colors which constructors are numbers from 0 to 3. And now I want to evaluate which color is more severe (has a higher number).所以我有一个数据类型Colors ,其构造函数是从 0 到 3 的数字。现在我想评估哪种颜色更严重(具有更高的数字)。 I tried this code我试过这段代码

data Color = Green | Yellow | Orange | Red

severity :: Color -> Integer
severity Green = 0
severity Yellow = 1
severity Orange = 2
severity Red = 3

moreSevere :: Color -> Integer -> Bool
moreSevere xs ys = if xs > ys then True
  else False

but it doesn't work and gives me an error:但它不起作用并给我一个错误:

Couldn't match expected type ‘Color’ with actual type ‘Integer’
    • In the second argument of ‘(>)’, namely ‘ys’
      In the expression: xs > ys
      In the expression: if xs > ys then True else False
   |
66 | moreSevere xs ys = if xs > ys then True

does any of you know how to solve this?你们有人知道如何解决这个问题吗?

So I have a data type "Colors" which constructors are numbers from 0 to 3所以我有一个数据类型“颜色”,其构造函数是从 0 到 3 的数字

no you don't.不,你不知道。 You have a data type whose constructors are Green , Yellow , Orange and Red – which makes sense as those are colours, whereas in my book 2 is not a colour.你有一个数据类型,其构造函数是GreenYellowOrangeRed —— 这是有道理的,因为它们是颜色,而在我的书中 2 不是颜色。

What is indeed “numbers from 0 to 3” are the severities of those colours.真正的“从 0 到 3 的数字”是这些颜色的严重程度 In your function, you're apparently trying to compare a given threshold to the severity of a colour.在您的 function 中,您显然是在尝试将给定阈值与颜色的严重程度进行比较。 So you need to write that too –所以你也需要写 -

       ... if severity xs > ys then ...

I don't like your choice of parameter names here – we usually use xs for some list (the elements of which would be x then), but you don't have any lists.我不喜欢你在这里选择的参数名称——我们通常使用xs来表示一些列表(那么它的元素就是x ),但你没有任何列表。 Why not为什么不

moreSevere c threshold = ...

Also, your if statement is superfluous: if cond then True else False is exactly the same as simply cond alone.此外,您的if语句是多余的: if cond then True else False与单独的cond完全相同。 So,所以,

moreSevere c threshold = severity c > threshold

You can shorten this further, using eta-reduction , to您可以使用eta-reduction将其进一步缩短为

moreSevere c = (severity c >)

or even甚至

moreSevere = (>) . severity

but that's a matter of taste.但这是一个品味问题。

You are simply reimplementing the existing Enum and Ord type classes.您只是重新实现现有的EnumOrd类型类。 The compiler can derive them for you.编译器可以为您导出它们。

data Color = Green | Yellow | Orange | Red deriving (Enum, Eq, Ord)

severity :: Color -> Integer
severity = fromEnum

moreSevere :: Color -> Color -> Bool
moreSevere = (>)

moreSevere' :: Color -> Integer -> Bool
moreSevere' c n = severity c > n

Thank you all for the answers.谢谢大家的回答。 I have to admit that i didn't quite understand your suggestions because this is my first semester of computer science and the things you suggested will I probably learn just later on: But I wanted to update you that I found another solution for it:我不得不承认我不太理解你的建议,因为这是我计算机科学的第一个学期,你建议的东西我可能会在以后学习:但我想告诉你我找到了另一个解决方案:

moreSevere :: Color -> Color -> Bool
moreSevere x y = if severity x > severity y then True
  else False

I think I just had to change the "Integer" for "Color".我想我只需要更改“颜色”的“整数”。 But thank you all for your help!但是谢谢大家的帮助!

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

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