繁体   English   中英

在 Haskell 中打印自定义数据类型

[英]Printing custom data type in haskell

我试图在 haskell 中学习类型类,但在表示和打印自定义数据类型类时遇到问题

这是我尝试过的,我的目标是打印值。

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)

我得到的Data constructor not in scope: TrafficLight :: TrafficLight -> t

TrafficLight是您的类型名称。

RedYellowGreen是构造函数。

您没有名称为TrafficLight数据构造TrafficLight

使固定:

x =  Red
y = (Red == Red)
z = (Red == Yellow)

线

data TrafficLight = Red | Yellow | Green deriving(Show)

一次定义三个不同的东西:

  • 一种名为TrafficLight的新类型

  • 该类型的三个构造函数,称为RedYellowGreen 构造函数本身可以看作是包含数据类型的n 元函数(在这种情况下没有包含的数据,所以构造函数是“空的”——换句话说,根本不是函数)到你的类型定义。 IE

     Red :: TrafficLight Yellow :: TrafficLight Green :: TrafficLight

    (通常,例如对于data Foo = Quz Int | Ruz Char Bool ,它将是Quz :: Int -> FooRuz :: Char -> Bool -> Foo 。)

    您似乎很困惑,因为在例如 C++ 或 Python 中,构造函数的调用名称与您定义的类(以及类型)相同,但在 Haskell 中,构造函数可以与类型相同,也可以不同。 按照惯例,如果只有一个构造函数,它往往被称为与类型相同的,如果有多个构造函数,它们都被称为不同的。 例如,如果您定义了

    data TrafficLight' = TrafficLight' { redLightOn :: Bool , yellowLightOn :: Bool , greenLightOn :: Bool }

    然后要在当前数据类型中生成对应于Red的值,您可以编写TrafficLight' True False False

    与 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

    这将允许您使用例如Red()并获得可用作TrafficLight类型值的值。
    (在 Python 中,类型关系当然有点无意义......)
    (是的,我知道 Python 也有 Enum 类型可以更好地解决这个特定问题。)

  • 一个Show实例,就像你也可以单独写一样

    instance Show TrafficLight where show = ...

因为RedYellowGreen实际上是TrafficLight类型的值, TrafficLight您可以像在源文件或 REPL 中那样简单地使用它们

Prelude> data TrafficLight = Red | Yellow | Green deriving(Show)
Prelude> Red
Red

您还可以在更大的表达式中添加本地签名

Prelude> (Red :: TrafficLight, 37)
(Red,37)

...但没有意义的是直接在值级代码中使用名称TrafficLight

暂无
暂无

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

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