Home > Back-end >  I keeping the error "error on parsing on input ins"
I keeping the error "error on parsing on input ins"

Time:02-01

module HW2sol 
where import HW2types

ins :: Eq a => a -> Bag a -> Bag a
ins x [] = [(x,1)]
ins x (y:ys) =
    if x == fst y
        then (x, snd y   1) : ys
        else y : (ins x ys)

HMW2types in this code is just a file that contains all of the declarations for the bag type. I have even copied and pasted other functions from online and they get the same error. This function takes an element and adds it to a bag.

[2 of 2] Compiling HW2sol ( HMW2sol.hs, HMW2sol.o )

HMW2sol.hs:5:1: parse error on input `ins'

CodePudding user response:

You may be aware of Haskell's indentation rules. Anywhere you have a block of declarations (as in a let <decls> in <expr>, or a where, etc) or a block of statements (as in a do block), Haskell identifies the start of each definition by the following logic:

  1. Identify the column of the first character of the first entry in the block. Call this column C.
  2. The next line that is indented less than C indicates the end of the block (and is not part of the block).
  3. Before the end of the block, any line that is indented exactly C characters starts a new entry in the block.
  4. Before the end of the block, any line that is indented more than C is a continuation line of the previous entry

This logic is consistently applied to all of Haskell's "block" constructs. They all have to be aligned this way1. And it turns out that the declarations in a module form an aligned block! We just don't usually bother to think of them that way because they are conventionally started at column 1 (which means it isn't possible to end the block as no line can start before the first column; people normally just put all their top-level declarations at the start of the line and indent any continuations without ever thinking about "aligning the module's main block).

However, your code does not (successfully) use this conventional layout. Because you didn't insert a linebreak after the where, he first declaration begins at column 7, not column 1!

where import HW2types
      ^
1234567

Your type declaration of ins begins on column 1, so by rule 2 above (1 is less than 7) this indicates the end of the module's block of definitions; the compiler has to parse ins :: Eq a => ... as something that can follow the main block in the module, instead of parsing it as a declaration in the main block. That's why you get a parse error (nothing can follow the main block).

If you start your module's main block at column 7 then all of your declarations have to be indented to column 7. This actually works:

module HW2sol 
where import HW2types

      ins :: Eq a => a -> Bag a -> Bag a
      ins x [] = [(x,1)]
      ins x (y:ys) =
          if x == fst y
              then (x, snd y   1) : ys
              else y : (ins x ys)

However you'll probably find it much easier to simply put a line break after the where and have import HW2types on a new line.


1 Alternatively, blocks and their entries can be explicitly delimited with braces and semicolons. But this is not usual style in Haskell.

  • Related