我是Haskell的新手,我想制作一个包含列表的程序。我想从键盘下一个元素读取,并将所有内容追加到我现有的列表中。由于我使用了数据类型,因此我不知道如何在名为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)
答案 0 :(得分:7)
首先我建议你实际使用这些类型的同义词,如果你完全定义它们的话:
data Car = Car Name Model Color Year Price Coin
deriving (Show)
请注意,这完全等同于声明所有字段String
(因为Model
和String
只是完全相同类型的不同名称),所以更清楚地阅读。如果你使用record fields作为这样的类型,可能更清楚,但这在这里没有什么区别。
现在要从某些字符串属性“创建”新车,您希望不将这些属性连接到列表。相反,只需使用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
OTOH,[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
实际上已经添加了两辆车。当然,只有整个程序实际上在循环中运行时才有意义。 (事实上,“循环”仍然意味着递归。)
答案 1 :(得分:3)
你可能已被告知,Haskell&#34;变量&#34;是不可变的。这意味着你必须明确地将状态作为循环中的参数传递。
例如,这是一个循环,会反复询问用户颜色:
loop1 = do putStrLn "Enter a color: "
color <- getLine
loop1
然而,用户的输入没有被保存&#34;任何地方。下一步是跟踪所有先前的输入作为循环函数的参数:
loop2 colors = do putStrLn $ "Previous colors: " ++ show colors
putStrLn "Enter a color: "
color <- getLine
loop2 (color:colors)
希望这有帮助。