-4

I'm new to Haskell and while reading real-world Haskell I came across a problem:

Q) Using the command framework from the earlier section “A Simple Command-Line Framework” on page 71, write a program that prints the first word of each line of its input.

The command framework is:

-- file: ch04/InteractWith.hs
-- Save this in a source file, e.g., Interact.hs

import System.Environment (getArgs)

interactWith function inputFile outputFile = do
  input <- readFile inputFile
  writeFile outputFile (function input)

main = mainWith myFunction
  where mainWith function = do
      args <- getArgs
      case args of
        [input,output] -> interactWith function input output
        _ -> putStrLn "error: exactly two arguments needed"
-- replace "id" with the name of our function below
myFunction = id

My solution to the problem is:

-- file: ch04/InteractWith.hs
-- Save this in a source file, e.g., Interact.hs

import System.Environment (getArgs)

interactWith function inputFile outputFile = do
  input <- readFile inputFile
  writeFile outputFile (function input)

main = mainWith myFunction
  where mainWith function = do
      args <- getArgs
      case args of
        [input,output] -> interactWith function input output
        _ -> putStrLn "error: exactly two arguments needed"
-- replace "id" with the name of our function below
myFunction = concat (map (++"\n") (map head (map words (lines input))))

As per instructions, whenever I try to compile this program using ghc --make filename I get a parse error i.e.

error: parse error on input ‘args’
   |
36 |       args <- getArgs
   |       ^^^^
Rahat
  • 305
  • 1
  • 4
  • 10

1 Answers1

3

Your indentation is off.

Haskell is sensitive to whitespace. In particular, among other things, the "inside" of a "block" must generally be indented farther to the right than the beginning of that block. In your case this means that the inside of do must be indented to the right of mainWith on the preceding line.

Try this:

main = mainWith myFunction
  where mainWith function = do
          args <- getArgs
          case args of
            [input,output] -> interactWith function input output
            _ -> putStrLn "error: exactly two arguments needed"
Fyodor Soikin
  • 78,590
  • 9
  • 125
  • 172
  • It solved the first error but now it gives me a new one. – Rahat Dec 27 '19 at 00:34
  • 2
    Well, if you have a different question, feel free to post it to StackOverflow. I'm sure somebody will be able to answer. – Fyodor Soikin Dec 27 '19 at 00:36
  • Couldn't match expected type ‘String -> String’ with actual type ‘[Char]’ In the first argument of ‘mainWith’, namely ‘myFunction’ In the expression: mainWith myFunction In an equation for ‘main’: main = mainWith myFunction where mainWith function = do args <- getArgs | 34 | main = mainWith myFunction | Variable not in scope: input :: String | 41 | myFunction = concat (map (++"\n") (map head (map words (lines input)))) – Rahat Dec 27 '19 at 01:07
  • Sorry, something weird is happening with my internet, the other comment wasn't being posted. Also sorry for the horrible formatting – Rahat Dec 27 '19 at 01:09