It’s me again:). I try to write a program which copies lines which number is divisible by 5 to another file. Here is code (sorry for Polish names):
import IO
przepiszConHelper :: Handle -> Handle -> Integer -> Integer -> IO ()
przepiszConHelper wejscie wyjscie liczba licznik = do
eof <- hIsEOF wejscie
if eof then return ()
else
linia <- hGetLine wejscie
if (mod licznik liczba) == 0 then
hPutStrLn wyjscie linia
przepiszConHelper wejscie wyjscie liczba (licznik + 1)
przepiszCon :: String -> String -> Integer -> IO ()
przepiszCon wejscie wyjscie liczba = do
wej <- openFile wejscie ReadMode
wyj <- openFile wyjscie WriteMode
przepiszConHelper wej wyj liczba 0
hClose wej
hClose wyj
main = przepiszCoN "wejscie.txt" "wyjscie.txt" 5
I think it should works… but I get one, strange error:
przepisz.hs:6:9:
Parse error in pattern: if eof then return () else linia
Which makes no sense for me. I had been using the same expression in another programs and it worked like a harm. I tried to remove these lines and write them with different indentations (I remember that I had some issues with white-spaces before). But I still get the same error:(.
–edit
OK, I have first error… it’s just else do instead of else. But here comes another problem:
przepisz.hs:11:25: parse error on input `przepiszConHelper'
The problem is here:
Indeed, the problem is not whitespace–your issue is that you seem to expect a
doblock to extend inside subexpressions, which is not the case. Theelseclause needs to define its owndoblock:There’s another error after that, however:
You’re missing an
elseclause for thisif.ifis always an expression in Haskell, so it must always evaluate to something. If you want to express “do thisIOaction if the condition is true, otherwise do nothing” you can usereturn ():The standard library even includes the function
whento express this idea:If you wanted, you could rewrite the outer
ifexpression the same way, and get something like this: