我正在尝试编写一个从文件中逐行读取的函数:
readMyFile = do
contents <- readFile "input.txt"
if(null sStringV == True)
then do
let sStringV = lines contents
let sString = head sStringV
let sStringV = tail sStringV
return sString
else do
let sString = head sStringV
let sStringV = tail sStringV
return sString
我将sStringV声明为null
sStringV = null
当我编译此代码时,我收到以下错误。
Couldn't match expected type `[a0]' with actual type `[a1] -> Bool'
In the first argument of `null', namely `sStringV'
In the first argument of `(==)', namely `null sStringV'
In the expression: (null sStringV == True)
我不明白我的问题在哪里......
答案 0 :(得分:3)
null
是一个函数[a] -> Bool
,返回输入列表是否为空。因此,sStringV
的类型为[a] -> Bool
。
在if (null sStringV == True)
行
null
的参数应该是一个列表,而不是null
函数本身。
您似乎应该将sStringV
的声明更改为
sStringV :: String
sStringV = ""
但是,您应该知道let sStringV = lines contents
没有为sStringV
分配新值 - 它只声明一个隐藏旧定义的新变量sStringV
。您无法在sStringV
功能中修改readMyFile
。
看起来你正试图像使用命令式语言一样使用Haskell。
答案 1 :(得分:0)
null()不测试变量是否为null。 null()测试列表是否为空。关键词是 list ,即你必须在列表上调用null。所以你有两个选择:
1)您可以在空列表上调用null():
null [] -->True
2)您可以在包含以下内容的列表上调用null():
null [1, 2, 3] --> False
另请注意写作:
if(null sStringV == True)
是多余的。 null()将列表作为参数,如果列表为空则返回True,如果列表包含某些内容则返回False。因此,您需要写的只有:
if(null sStringV)
then do .... --executed if sStringV is an empty list
else do ... --excuted if sStringV is a list that contains something
以下是一个例子:
dostuff:: [a] -> IO ()
dostuff alist = if null alist
then putStrLn "hello"
else putStrLn "goodbye"
ghci>:l 1.hs
[1 of 1] Compiling Main ( 1.hs, interpreted )
Ok, modules loaded: Main.
ghci>dostuff []
hello
ghci>dostuff [1, 2, 3]
goodbye
ghci>