1

I'm learning Haskell and been writing an example program from a book. This module below won't compile and gives me the following error in ghci and ghc:

"Optimal.hs:15:23: parse error on input ‘=’"

Any ideas, I can't see it?


module Optimal (optimalPath) where

import RoadSystem

optimalPath :: RoadSystem -> Path
optimalPath roadSystem =
    let (bestAPath, bestBPath) = foldl roadStep ([], []) roadSystem
    in if sum (map snd bestAPath) <= sum (map snd bestBPath)
            then reverse bestAPath
            else reverse bestBPath

roadStep :: (Path, Path) -> Section -> (Path, Path)
roadStep (pathA, pathB) (Section a b c) =
    let timeA = sum (map snd pathA)
        timeB = sum (map snd pathB)
        forwardTimeToA = timeA + a
        crossTimeToA = timeB + b + c
        forwardTimeToB = timeB + b
        crossTimeToB = timeA + a + c
        newPathToA = if forwardTimeToA <= crossTimeToA
                        then (A, a):pathA
                        else (C, c):(B, b):pathB
        newPathToB = if forwardTimeToB <= crossTimeToB
                        then (B, b):pathB
                        else (C, c):(A, a):pathA
    in (newPathToA, newPathToB)
Andrey Chernukha
  • 21,488
  • 17
  • 97
  • 161
Andrew Mackenzie
  • 5,477
  • 5
  • 48
  • 70
  • 2
    Did you try to convert the tabs in spaces? AFAIK Haskell assumes the tab stop is *8* characters, so if in your editor you are using a different size the layout you are seeing is *not* what the compiler is actually using. There's even [a proposal](https://ghc.haskell.org/trac/haskell-prime/wiki/Tabs) to disallow tabs for indentation completely. – Bakuriu Aug 25 '14 at 07:36
  • your code is full of tabs. at the very least, *always* have a `let` keyword on its own line. – Will Ness Aug 25 '14 at 07:59

1 Answers1

7

Any ideas, I can't see it?

This is what happens when you use tabs for indentation. The Haskell standard mandates to assume a tabstop of 8 characters, so the compiler is actually thinking that your code is:

module Optimal (optimalPath) where

import RoadSystem

optimalPath :: RoadSystem -> Path
optimalPath roadSystem =
        let (bestAPath, bestBPath) = foldl roadStep ([], []) roadSystem
        in if sum (map snd bestAPath) <= sum (map snd bestBPath)
                then reverse bestAPath
                else reverse bestBPath

roadStep :: (Path, Path) -> Section -> (Path, Path)
roadStep (pathA, pathB) (Section a b c) =
        let timeA = sum (map snd pathA)
                timeB = sum (map snd pathB)
                forwardTimeToA = timeA + a
                crossTimeToA = timeB + b + c
                forwardTimeToB = timeB + b
                crossTimeToB = timeA + a + c
                newPathToA = if forwardTimeToA <= crossTimeToA
                                                then (A, a):pathA
                                                else (C, c):(B, b):pathB
                newPathToB = if forwardTimeToB <= crossTimeToB
                                                then (B, b):pathB
                                                else (C, c):(A, a):pathA
        in (newPathToA, newPathToB)

And sure enough near line 15, character 23 you have:

        let timeA = sum (map snd pathA)
                timeB = sum (map snd pathB)

which is a syntax error.

To fix it:

  • Don't use tabs for indentation. Every editor allows you to configure the tab key to insert a configurable number of spaces instead of one tab, so there's no "I have to press the space bar many times" problem.
  • Use a tabstop of 8 in your editor. Note that if you send code to someone else he might have the same problem when modifying the code.
Bakuriu
  • 98,325
  • 22
  • 197
  • 231
  • Thanks I'll fix it. This time I was trying to write in IntelliJ, using the plug-in. It seems it doesn't have a code-style with settings for tabs for Haskell :-( – Andrew Mackenzie Aug 26 '14 at 07:47
  • @Andrew I believe you can go in the *Settings...* page, under the project settings there should be a *Code Style* item in the list on the left. Select the Haskell language and you should see a *Tabs and Indents* tab on the right, underwhich you can deselect the *Use tab character* checkbox and choose the width of the indent. – Bakuriu Aug 26 '14 at 08:18
  • OK. I now have zero tabs, and still get the error reported on the equals.... – Andrew Mackenzie Aug 26 '14 at 20:19
  • I don't have a Haskell code style in my settings. :-( Just updated the (JetBrains) plug-in to be sure....nope. – Andrew Mackenzie Aug 26 '14 at 20:23
  • @Andrew Unfortunately I don't have IntelliJ IDEA installed (I commented based on what I see in PyCharm). However I'm sure that such an option exists somewhere. Try to open the settings pages and search for *tab* or *indent* and something should come up. – Bakuriu Aug 26 '14 at 20:38
  • I can change globally, but don't want to do that for other projects I have - and no Haskell specific options exist. Horrible language feature BTW! I have tried multiple combinations without success :-( Here is the file as it stands https://github.com/andrewdavidmackenzie/router/blob/master/haskell/src/Optimal.hs – Andrew Mackenzie Aug 26 '14 at 20:44
  • @Andrew I believe settings *are* per-project, and I believe there *must* be per language and/or per file-type settings. See [here](http://www.jetbrains.com/idea/webhelp/project-settings.html) for the settings available on a per-project basis.Also you could use the [general](http://www.jetbrains.com/idea/webhelp/general.html) code style setting to use spaces instead of tabs (note: the general settings are applied only when a more specific setting cannot be found, so your Java files will still use the old settings). Anyway, IMHO, using spaces in other project as well would be a better solution. – Bakuriu Aug 26 '14 at 20:56