![](/img/trans.png)
[英]Understanding haskells data types and constructors (specifically where you use another data type in a data type)
[英]Haskells data types and constructors with functions?
我是Haskell的新手,正在研究基本數據類型和具有函數的構造函數。
我已經完成了以下代碼:
data Name = Name String deriving (Show)
data Age = Age Int deriving (Show)
data Iq = Iq Int deriving (Show)
data Language = Language String deriving (Show)
data DataSubject = DSInformation Name Age Iq Language | DSConstruct {name :: String, age :: Int, iq :: Int, language :: String} deriving (Show)
makeDataSubject :: DataSubject -> DataSubject --Take in info and output a record
makeDataSubject (DSInformation (Name n) (Age a) (Iq i) (Language l)) = (DSConstruct {name = n, age = a, iq = i, language = l})
main = do
let x = makeDataSubject $ (DSInformation (Name "Ron") (Age 34) (Iq 100) (Language "French"))
putStrLn $ show x
運行良好,但是似乎太冗長了-我如何使它變得更好?
您的大多數data
聲明都可能是簡單的type
別名。
type Name = String
type Age = Int
type Iq = Int
type Language = String
使用這些別名, DataSubject
的兩個構造函數之間沒有顯着差異(除了記錄語法)。 擺脫一個,並省去makeDataSubject
。 (除非您希望封裝一些邏輯或防止模式匹配,否則您不需要智能構造函數即可執行操作。)
data DataSubject = DS { name :: Name
, age :: Age
, iq :: Iq
, language :: Language
} deriving (Show)
main = do
let x = DS { name="Ron", age=34, iq=100, language="French"}
putStrLn $ show x
如果確實需要實類型,而不僅僅是別名,請使用newtype
而不是data
。
newtype Name = Name String deriving Show
newtype Age = Age Int deriving Show
newtype Iq = Iq Int deriving Show
newtype Language = Language String deriving Show
data DataSubject = DS { name :: Name
, age :: Age
, iq :: Iq
, language :: Language
} deriving (Show)
main = do
let x = DS { name=Name "Ron", age=Age 34, iq=Iq 100, language=Language "French"}
putStrLn $ show x
您可能想在此處添加一個智能構造函數,但要讓它把每條數據作為一個單獨的參數(包裝的或展開的),而不是一個已經是同構的返回值的參數。 (也就是說,您的構造函數本質上是身份函數,而不是對輸入進行一些重新包裝。)
makeDataSubject :: String -> Int -> Int -> String -> DataSubject
makeDataSubject name age iq lang = DS {name=Name name, age=Age age, iq=Iq iq, language=Language lang}
要么
makeDataSubject' :: Name -> Age -> Iq -> Language -> DataSubject
makeDataSubject' name age iq lang = DS {name=name, age=age, iq=iq, language=lang}
不幸的是,您遇到了Haskell的弱點之一:記錄系統。 如果我們有某種表示法來表示subject.name
和subject.age
而不是顯式地進行銷毀,那將是很好的選擇,但是現在沒有很好的答案。 但是,GHC 8中即將進行的工作應該盡快解決該問題,並且在問題空間中有各種各樣的庫正在工作。 但是,對於這個問題,我們可以采用一個簡單的技巧: -XRecordWildcards
。
{-# LANGUAGE RecordWildCards #-}
module Main where
newtype Name = Name String deriving Show
newtype Age = Age Int deriving Show
newtype Iq = Iq Int deriving Show
newtype Language = Language String deriving Show
data DataSubject =
DSInformation Name Age Iq Language
| DSConstruct {name :: String, age :: Int, iq :: Int, language :: String}
deriving Show
-- | Take in info and output a record
makeDataSubject :: DataSubject -> DataSubject
makeDataSubject (DSInformation (Name name) (Age age) (Iq iq) (Language language)) =
DSConstruct {..}
main :: IO ()
main =
print . makeDataSubject $ DSInformation (Name "Ron") (Age 34) (Iq 100) (Language "French")
通過分解為字段的名稱, {..}
將選擇范圍內的那些綁定以自動填充字段。 您絕對希望在編譯期間打開-Wall -Werror
,因為現在比以往任何時候都更容易拼寫錯誤並忘記填充字段,然后最終得到部分記錄(記錄系統的另一個缺陷)字段undefined
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.