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