[英]Haskell data type list
我是Haskell的新手,我想制作一個帶有列表的程序。 我想從鍵盤上的下一個元素讀取內容,並將所有內容添加到現有列表中。 因為我使用的是數據類型,所以我不知道如何在所有名為cars
列表中添加具有所有這些詳細信息的cars
。 我知道序列let ls = name:model:color:year:price:coin:[cars]
是錯誤的,我也不知道如何使它工作。 誰能給我一個想法,請問我在這里可以做什么?
type Name = String
type Model = String
type Color= String
type Year = String
type Price = String
type Coin = String
data Car = Car String String String String String String deriving (Show)
cars :: [Car]
cars = [Car "Range Rover" "Sport Supercharged" "Blue" "2015" "85790" "$" , Car "BMW" "4-Series" "Black" "2014" "65489" "$"]
main = do
putStrLn "Car details "
putStr "Name: "
name <- getLine
putStr "Model: "
model <- getLine
putStr "Color: "
color <- getLine
putStr "Year: "
year <- getLine
putStr "Price: "
price <- getLine
putStr "Coin: "
coin <- getLine
let ls = name:model:color:year:price:coin:[cars]
putStrLn (show ls)
首先,如果您完全定義了它們,我建議您實際使用這些類型的同義詞:
data Car = Car Name Model Color Year Price Coin
deriving (Show)
請注意,這完全等同於聲明所有字段String
(因為Model
和String
只是完全相同類型的不同名稱),因此更容易閱讀。 如果您將記錄字段用於這種類型,則可能更清楚,但這在這里沒有什么區別。
現在,以“創造”一些字符串屬性一輛新車,你想不串聯這些屬性的列表。 相反,只需使用Car
構造函數並將單個汽車添加到列表中即可。
main = do
putStrLn "Car details "
putStr "Name: "
name <- getLine
...
let cars' = Car name model color year price coin : cars
print cars'
如果您想知道: Car foo bar baz : cars
與(Car foo bar baz) : (cars)
。 實際上, Car
就像這里的任何其他功能一樣被使用。 您還可以定義一個輔助函數
redCar :: Name -> Model -> Year -> Price -> Coin -> Car
redCar n m y p c = Car n m "red" y p c
然后寫
print $ redCar name model year price coin : cars
太太, [cars]
並不是您可以在其他汽車之前加入的汽車列表; 而是一個具有單個元素的列表(該元素是汽車列表)。
通常,在Haskell中,您是如何更新內容的另一主題。 ErikR解決了如何通過遞歸來實現這一點; 我會注意,您也可以在Haskell IO代碼正確可變的變量。 我們通常盡量避免在IO中工作,但是如果您實際上編寫了一個交互式應用程序,那么它就足夠明智了:
import Data.IORef
main = do
knownCars <- newIORef cars
putStrLn "Car details "
...
modifyIORef knownCars $ Car name model color year price coin
print =<< readIORef cars
然后,您可以按照以下步驟操作
putStrLn "Details of another car:"
...
modifyIORef knownCars $ Car name2 model2 color2 year2 price2 coin2
並實際上添加了兩輛車。 當然,這僅在整個程序實際上在循環中運行時才有意義。 (實際上,“循環”仍然意味着遞歸。)
如您所知,Haskell“變量”不是可變的。 這意味着您必須在循環中顯式傳遞狀態作為參數。
例如,這是一個循環,將反復要求用戶提供顏色:
loop1 = do putStrLn "Enter a color: "
color <- getLine
loop1
但是,用戶的輸入未在任何地方“保存”。 下一步是跟蹤所有先前的輸入作為循環函數的參數:
loop2 colors = do putStrLn $ "Previous colors: " ++ show colors
putStrLn "Enter a color: "
color <- getLine
loop2 (color:colors)
希望這會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.