将getLine输入与haskell数组连接会引发类型错误

将getLine输入与haskell数组连接会引发类型错误,haskell,do-notation,Haskell,Do Notation,我是Haskell的初学者,我来自js环境,我有一个简单的数组students,我想把一些student对象放入其中,但遗憾的是Haskell不支持对象(如果有办法的话,请指导我),所以我试着编写一个简单的程序来读取用户输入(数组)将其放入学生数组,以下是我尝试过的: main :: IO() main = do let students = [] studentArray <- getLine students ++ studentArray print(student

我是Haskell的初学者,我来自js环境,我有一个简单的数组
students
,我想把一些student对象放入其中,但遗憾的是Haskell不支持对象(如果有办法的话,请指导我),所以我试着编写一个简单的程序来读取用户输入(数组)将其放入
学生
数组,以下是我尝试过的:

main :: IO()
main = do 
  let students = []
  studentArray <- getLine
  students ++ studentArray
  print(students)
main::IO()
main=do
让学生=[]

studentArray首先,您可能需要查看中的资源。如果您还没有完成“绝对初学者”部分中的教程,那么这将是一个很好的起点

请参阅,对于其他编程语言,通常从在屏幕上打印“Hello,world!”
的程序开始,或者像您的示例一样,从控制台读取学生列表并将其打印出来。对于Haskell来说,一开始使用完全不同类型的程序通常更有意义。例如,本教程直到第9章才开始讲述“Hello,world!”,直到第15章才开始讲述(然后它只讲述了输出——输入直到第20章才出现)

无论如何,回到你的例子。问题在于行
students++studentArray
。这是一个表达式,它将空列表
students=[]
studentArray
的值连接起来,后者是由
getLine
检索的
字符串。由于
字符串
只是一个字符列表,空列表就是空字符串,因此您编写的是JavaScript函数的大致等价物:

函数main(){
var students=”“//空列表只是空字符串
var studentArray=readlinefromwhere()
students+studentArray//连接字符串并丢弃结果
console.log(students)//打印空字符串
}
在JavaScript中,这将运行并打印空字符串,因为
students+studentArray
行没有任何作用。在Haskell中,这不会进行类型检查,因为Haskell希望此
do
块中的所有(非
let
)行都是I/O操作:

main :: IO ()         -- signature forces `do` block to be I/O
main = do 
  let students = []          -- "let" line is okay
  studentArray <- getLine    -- `getLine` is IO action
  students ++ studentArray   -- **NOT** IO action:  it's a String AKA [Char]
  print students             -- `print students` is IO action
或者使用函数调用通过将标识符重新绑定到更新的值来模拟变量:

main :: IO ()
main = do
  putStrLn "Enter number of students:"
  n <- readLn
  putStrLn $ "Enter " ++ show n ++ " student names:"
  students <- getStudents n []
  print students

getStudents :: Int -> [String] -> IO [String]
getStudents 0 studentsSoFar = return studentsSoFar
getStudents n studentsSoFar = do
  student <- getLine
  getStudents (n-1) (studentsSoFar ++ [student])
main::IO()
main=do
putStrLn“输入学生人数:”
n IO[字符串]
GetStudents0 studentsFar=返回studentsFar
getStudents n studentsSoFar=do

学生你认为
students++studentArray
做什么?根据定义,
studentArray
[]++studentArray
是一样的——你可以写它,而不会有任何改变。同样,最后一行相当于
print[]
。这显然不是您想要的:您正在尝试在Haskell中变异一个变量,该变量旨在防止您执行变异。您需要按照纯粹的功能性方法(而非命令性方法)重写代码。。
main :: IO ()
main = do
  putStrLn "Enter number of students:"
  n <- readLn
  putStrLn $ "Enter " ++ show n ++ " student names:"
  students <- getStudents n []
  print students

getStudents :: Int -> [String] -> IO [String]
getStudents 0 studentsSoFar = return studentsSoFar
getStudents n studentsSoFar = do
  student <- getLine
  getStudents (n-1) (studentsSoFar ++ [student])