1

我正在尝试编写一个函数来逐行读取文件:

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)

我不明白我的问题在哪里...

4

2 回答 2

3

null是一个函数[a] -> Bool,返回输入列表是否为空。因此sStringV有类型[a] -> Bool

在行if (null sStringV == True)

to 的参数null应该是一个列表,而不是null函数本身。

看来您应该将声明更改为sStringV类似

sStringV :: String
sStringV = ""

但是,您应该知道它let sStringV = lines contents不会分配新值sStringV- 它仅声明一个sStringV隐藏旧定义的新变量。您不能sStringV从您的readMyFile函数中进行修改。

看起来您正在尝试像使用命令式语言一样使用 Haskell。

于 2013-06-07T08:09:14.593 回答
0

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>
于 2013-06-07T08:31:27.153 回答