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