Reputation:
I`m trying to write a function for reading line by line from a file:
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
and I declared sStringV as null
sStringV = null
When I compile this code I'm getting the following error.
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)
I don't understand where my problem is...
Upvotes: 1
Views: 4249
Reputation: 48599
null() does not test whether a variable is null. null() tests whether a list is empty. The key word is list, i.e. you have to call null on a list. So you have two choices:
1) You can call null() on an empty list:
null [] -->True
2) You can call null() on a list that contains something:
null [1, 2, 3] --> False
Also note that writing:
if(null sStringV == True)
is redundant. null() takes a list as an argument and returns True if the list is empty, and False if the list contains something. Therefore, all you need to write is:
if(null sStringV)
then do .... --executed if sStringV is an empty list
else do ... --excuted if sStringV is a list that contains something
Here is an example:
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>
Upvotes: 0
Reputation: 144136
null
is a function [a] -> Bool
and returns whether the input list is empty. Therefore sStringV
has type [a] -> Bool
.
In the line if (null sStringV == True)
the argument to null
should be a list, not the null
function itself.
It seems you should change the declaration of sStringV
to something like
sStringV :: String
sStringV = ""
However, you should be aware that let sStringV = lines contents
does not assign a new value to sStringV
- it only declares a new variable sStringV
which hides the old definition. You can't modify sStringV
from within your readMyFile
function.
It looks like you're trying to use Haskell like an imperative language.
Upvotes: 3