[英]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
是您的类型名称。
Red
, Yellow
, Green
是构造函数。
您没有名称为TrafficLight
数据构造TrafficLight
。
使固定:
x = Red
y = (Red == Red)
z = (Red == Yellow)
线
data TrafficLight = Red | Yellow | Green deriving(Show)
一次定义三个不同的东西:
一种名为TrafficLight
的新类型。
该类型的三个构造函数,称为Red
、 Yellow
和Green
。 构造函数本身可以看作是包含数据类型的n 元函数(在这种情况下没有包含的数据,所以构造函数是“空的”——换句话说,根本不是函数)到你的类型定义。 IE
Red :: TrafficLight Yellow :: TrafficLight Green :: TrafficLight
(通常,例如对于data Foo = Quz Int | Ruz Char Bool
,它将是Quz :: Int -> Foo
和Ruz :: 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 = ...
因为Red
、 Yellow
和Green
实际上是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.