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