[英]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.