[英]Printing custom data type in haskell
I was trying to learn type classes in haskell and have trouble representing and printing custom data type classes我试图在 haskell 中学习类型类,但在表示和打印自定义数据类型类时遇到问题
Here's what I tried, my goal is to print the value.这是我尝试过的,我的目标是打印值。
data TrafficLight = Red | Yellow | Green deriving(Show)
instance Eq TrafficLight where
Red == Red = True
_ == _ = False
main = do
print x
print y
print z
where
x = (TrafficLight Red)
y = (TrafficLight Red == TrafficLight Red)
z = (TrafficLight Red == TrafficLight Yellow)
I'm getting Data constructor not in scope: TrafficLight :: TrafficLight -> t
我得到的Data constructor not in scope: TrafficLight :: TrafficLight -> t
TrafficLight
is name of your type. TrafficLight
是您的类型名称。
Red
, Yellow
, Green
are constructors. Red
, Yellow
, Green
是构造函数。
You don't have data constructor with name TrafficLight
.您没有名称为TrafficLight
数据构造TrafficLight
。
FIX:使固定:
x = Red
y = (Red == Red)
z = (Red == Yellow)
The line线
data TrafficLight = Red | Yellow | Green deriving(Show)
defines three different things at once:一次定义三个不同的东西:
A new type called TrafficLight
.一种名为TrafficLight
的新类型。
Three constructors for that type, called Red
, Yellow
and Green
.该类型的三个构造函数,称为Red
、 Yellow
和Green
。 A constructor itself can be seen as an n -ary function from the contained data types (in this case there is no contained data, so the constructors are “nullary” – in other words, not functions at all) to the type you're defining.构造函数本身可以看作是包含数据类型的n 元函数(在这种情况下没有包含的数据,所以构造函数是“空的”——换句话说,根本不是函数)到你的类型定义。 Ie IE
Red :: TrafficLight Yellow :: TrafficLight Green :: TrafficLight
(In general, eg for data Foo = Quz Int | Ruz Char Bool
, it would be Quz :: Int -> Foo
and Ruz :: Char -> Bool -> Foo
.) (通常,例如对于data Foo = Quz Int | Ruz Char Bool
,它将是Quz :: Int -> Foo
和Ruz :: Char -> Bool -> Foo
。)
You seem to be confused because in eg C++ or Python, constructors are invoked with the same name as the class (and thus type) you're defining, but in Haskell constructors can either be called the same as the type, or different.您似乎很困惑,因为在例如 C++ 或 Python 中,构造函数的调用名称与您定义的类(以及类型)相同,但在 Haskell 中,构造函数可以与类型相同,也可以不同。 By convention, if there's just a single constructor it tends to be called the same as the type, if there are multiple constructors they're all called different.按照惯例,如果只有一个构造函数,它往往被称为与类型相同的,如果有多个构造函数,它们都被称为不同的。 For example, if you had defined例如,如果您定义了
data TrafficLight' = TrafficLight' { redLightOn :: Bool , yellowLightOn :: Bool , greenLightOn :: Bool }
then to generate a value corresponding to Red
in your current data type, you would write TrafficLight' True False False
.然后要在当前数据类型中生成对应于Red
的值,您可以编写TrafficLight' True False False
。
An OO analogue to Haskell's multi-constructor types would be an abstract base class with a specific number of child classes, like与 Haskell 的多构造函数类型类似的 OO 是具有特定数量子类的抽象基类,例如
class TrafficLight: # could inherit `abc.ABC` to make it pass # explicitly abstract class Red(TrafficLight): def __init__(self): pass class Yellow(TrafficLight): def __init__(self): pass class Green(TrafficLight): def __init__(self): pass
which would allow you to use eg Red()
and get a value that can be used as a value of type TrafficLight
.这将允许您使用例如Red()
并获得可用作TrafficLight
类型值的值。
(In Python, the typing relationships are of course somewhat meaningless...) (在 Python 中,类型关系当然有点无意义......)
(Yes, I know Python also has Enum types which solve this particular problem better.) (是的,我知道 Python 也有 Enum 类型可以更好地解决这个特定问题。)
A Show
instance, like you could also write separately一个Show
实例,就像你也可以单独写一样
instance Show TrafficLight where show = ...
Because Red
, Yellow
and Green
are actually values of type TrafficLight
, you can simply use them like that in your source file or at the REPL因为Red
、 Yellow
和Green
实际上是TrafficLight
类型的值, TrafficLight
您可以像在源文件或 REPL 中那样简单地使用它们
Prelude> data TrafficLight = Red | Yellow | Green deriving(Show)
Prelude> Red
Red
You could also add a local signature within a bigger expression您还可以在更大的表达式中添加本地签名
Prelude> (Red :: TrafficLight, 37)
(Red,37)
...but what doesn't make sense is use the name TrafficLight
directly in value-level code. ...但没有意义的是直接在值级代码中使用名称TrafficLight
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.