繁体   English   中英

Haskell数据类型列表

[英]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 (因为ModelString只是完全相同类型的不同名称),因此更容易阅读。 如果您将记录字段用于这种类型,则可能更清楚,但这在这里没有什么区别。

现在,以“创造”一些字符串属性一辆新车,你想串联这些属性的列表。 相反,只需使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM