简体   繁体   English

Haskell-用户输入存储在列表中

[英]Haskell - User Input Stored in a List

I'm looking to take a user input and store it as a list, which I would later be able to search. 我希望接受用户输入并将其存储为列表,以后可以进行搜索。 At the moment I have an empty list called "sales" and this function to take an input and store it in this list. 目前,我有一个名为“ sales”的空列表,该函数可以接受输入并将其存储在此列表中。

sales = []

recordPurchase ::  IO ()
recordPurchase = do
    putStrLn "Manufacturer"
    manufacturer <- getLine
    putStrLn "Product Name"
    product <- getLine
    let sales = sales ++ [manufacturer, product]
    print sales

At the moment I get an 此刻我得到一个

"*** Exception: <<loop>>"

error. 错误。 This particular error is solved now, it was due to the line 现在解决了此特定错误,这是由于该行

let sales = sales ++ [manufacturer, product]

However I'm not sure how to combine two lists it seems. 但是我不确定如何合并两个列表。 Even when it was "working" I was still getting an empty list when sales was printed. 即使当它正在“工作”时,在打印销售时我仍然得到一个空白清单。 I don't know whether I'm even on track here, particularly with the function definition as "IO()". 我不知道我是否在这里,特别是函数定义为“ IO()”。

The bonus part here is if I was able to populate a list, how would I then be able to search it and display certain elements, such as products by a specific manufacturer? 这里的奖励部分是,如果我能够填充列表,那么我将如何搜索列表并显示某些元素,例如特定制造商的产品?

You cannot mutate variables in Haskell. 您无法在Haskell中对变量进行突变。 All Haskell variables are immutable. 所有Haskell变量都是不可变的。

-- `sales` is now defined as `[]`. It cannot be changed, ever.
sales = []

recordPurchase ::  IO ()
recordPurchase = do
    putStrLn "Manufacturer"
    manufacturer <- getLine
    putStrLn "Product Name"
    product <- getLine
    -- Here, you define a new value called `sales`,
    -- which is recursively defined, since it refers to itself. 
    -- This causes a loop.
    let sales = sales ++ [manufacturer, product]
    print sales

To see why this causes a loop, consider the definition of sales as an equation: sales = sales ++ [manufacturer, product] : 要了解为什么会导致循环,请考虑将sales的定义视为一个等式: sales = sales ++ [manufacturer, product]

  sales
= sales ++ [manufacturer, product]
= sales ++ [manufacturer, product] ++ [manufacturer, product]
= sales ++ [manufacturer, product] ++ [manufacturer, product] ++ [manufacturer, product]
= (etc)

What you probably mean is this: 您可能的意思是:

recordPurchase ::  IO ()
recordPurchase = do
    putStrLn "Manufacturer"
    manufacturer <- getLine
    putStrLn "Product Name"
    product <- getLine
    print [manufacturer, product]

The usual way of storing data, however, is recursion. 但是,存储数据的常用方法是递归。 We'd do it a bit like this (pseudocode): 我们会这样做(伪代码):

mainLoop :: [String] -> IO ()
mainLoop sales = do
    -- Get new sales info
    newInfo <- getNewInfo

    -- Define a new list with the extra info
    let newSales = sales ++ [newInfo]

    -- Do something with the sales info, e.g. print it
    print newInfo

    -- Go through the 'loop' again, with the new sales info.
    mainLoop newSales

 -- The main program is just the main loop with initial value of `[]`:
 main = mainLoop []

@Carcigenicate is right. @Carcigenicate是正确的。 The compiler thinks that when you type 编译器认为当您键入

let sales = sales ++ [manufacturer, product]

you're defining sales in terms of itself. 您是根据自身来定义sales

You don't seem to be storing additional entries, so why not just do 您似乎没有存储其他条目,所以为什么不这样做

print [manufacturer, product]

since your program exits right afterwards? 因为您的程序会随后退出?

EDIT: Since you want to have your program keep running, you're going to have to be cleverer about storing data. 编辑:由于您希望程序继续运行,因此您将不得不更聪明地存储数据。 Haskell data structures are immutable. Haskell数据结构是不可变的。 You may want to check out the State monad, which handles stateful computations in functional way. 您可能要签出State monad,它以功能方式处理有状态计算。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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