Futarimiti
Futarimiti

Reputation: 685

Indented import statement causes parsing error in stylish-haskell

When trying to format the following test programme Char.hs, stylish-haskell reports a parsing error:

module Char (caesarCipher, caesarDecipher)
    where

    import Data.Char (ord, chr)

    caesarCipher :: Int -> [Char] -> [Char]
    caesarCipher shift msg = map (chr) $ map (+ shift) $ map (ord) msg

    caesarDecipher :: Int -> [Char] -> [Char]
    caesarDecipher shift msg = map (chr) $ map (subtract shift) $ map (ord) msg

Part of the verbose log by stylish-haskell:

$ stylish-haskell -v Char.hs          
...
Stylish Haskell will work basing on LANGUAGE pragmas in source files.
Enabled Cases step
Enabled Imports (ghc-lib-parser) step
Enabled LanguagePragmas step
Enabled TrailingWhitespace step
Extra language extensions: []
Char.hs: <string>:6:5: error: parse error on input `caesarCipher'

Where stylish-haskell has not been configured with any config files as reflected in the folded part of the verbose report; Char.hs is a standalone non-project file, and nothing did GHC complain throughout compilation:

$ ghc Char.hs   
[1 of 1] Compiling Char             ( Char.hs, Char.o )

After some testing, the problem seems to be about the import statement, in which:

Where the only thing making stylish-haskell unhappy seems to be the indented import statement. Just to clarify, I know import statements must be on the same indentation level as the others and I did not violate that in any situation; I've always been using the space character instead of tabs and I never mix them in any instances.


Therefore, my questions are:

To whom may be interested in, I'm using GHC 8.10.7 and stylish-haskell 0.14.1.0. Just shout to me if you need more info.

Upvotes: 0

Views: 216

Answers (1)

Laar
Laar

Reputation: 614

The indentation rules of Haskell are formally specified in section 10.3 of the Haskell report and a simplified version is given in section 2.7.

My understanding is the following (in the context of your programs).

  1. The body of your program is a list of imports and top level declarations.
  2. When using the layout rule all of these must have the same indentation.
  3. The level of indentation is determined by the first declaration after the where from module.

So based on this all of the above programs should be correct. Though with a rather unconventional indentation.

Notes:

  1. The body is everything that comes after module ...... where
  2. The alternative to using the layout rule is to manually add braces {, } and semicolons ; to separate declarations, similar to how this is done in languages like C. This gives you a 'layout-insensitive program'
  3. The actual definition of the Haskell syntax uses braces and semi-colons. The specification describes how the layout of your file can be translated into a layout-insensitive. See again 1 for the complete description of the algorithm and the following section 10.5 for the actual Haskell syntax definition.

Upvotes: 0

Related Questions