Andy
Andy

Reputation: 3522

Haskell: The last statement in a 'do' construct must be an expression

Hey, sorry to dump the error message here but I've tried everything I can find and nothing seems relevant. This code is generating the error:

import System.Environment   
import System.Directory  
import System.IO  
import Data.List  

data Node = PathNode String Float Float [String] | NoNode deriving (Show)


main = do
    (filename:args) <- getArgs  
    load filename


load :: String -> IO ()  
load fileName = do
    contents <- readFile fileName  
    let pathStrings = lines contents
        first = head pathStrings
        args = lines first
        path = createNode args
        putStr path


createNode [String] -> Node
createNode (name:x:y:paths) = PathNode name x y paths
createNode [] = NoNode

I know its something to do with alignment, but I have aligned all the calls in the 'load' function correctly. What am I doing wrong?

Thanks -A

Upvotes: 3

Views: 1507

Answers (2)

Fiona Runge
Fiona Runge

Reputation: 2311

Only errors I can find besides identation are: in load: putStr expects String, whereas path is of type Node. in createNode: Pathnode needs x and y to be of type Float, whereas you give Strings.

load :: String -> IO ()  
load fileName = do
    contents <- readFile fileName  
    let pathStrings = lines contents
        first = head pathStrings
        args = lines first
        path = createNode args
    putStr $ show path


createNode :: [String] -> Node
createNode (name:x:y:paths) = PathNode name (read x) (read y) paths
createNode [] = NoNode

This solves both type errors described by using show and read.

Upvotes: 3

Heinrich Apfelmus
Heinrich Apfelmus

Reputation: 11064

The last line in the do expression is indented too far.

Also, you can just write

load :: String -> IO ()  
load fileName =
    putStr . createNode . lines . head . lines =<< readFile filename

Upvotes: 6

Related Questions