parse error on input '->' when using case [duplicate] - haskell

This question already has an answer here:
Why shouldn't I mix tabs and spaces?
(1 answer)
Closed 5 years ago.
I'm learning haskell by going through learn you a haskell for great good and one of the functions in the tutorials doesn't seem to compile. I can't figure out why, I thought it might be the indenting but it doesn't seem to make a difference. Most of the SE questions seems to be referring to the ghci and trying to set variables.
describeList :: [a] -> String
describeList xs = "The list is " ++ case xs of [] -> "empty."
[x] -> "a singleton list."
xs -> "a longer list."
The error I get is:
describeList.hs:4:95: parse error on input '->'
Failed, modules loaded: none.

Turns out the problem was with my tab settings on VIM. Turns out Haskell is quite particular with the indentations. I changed my vimrc file to these settings.
" Tab specific option
set tabstop=8 "A tab is 8 spaces
set expandtab "Always uses spaces instead of tabs
set softtabstop=4 "Insert 4 spaces when tab is pressed
set shiftwidth=4 "An indent is 4 spaces
set shiftround "Round indent to nearest shiftwidth multiple
Source: http://www.haskell.org/haskellwiki/Vim

Related

When to use tabs and when to use spaces in Haskell?

I am wondering when I should use tabs and when I should use spaces?
Especially in guards, I'm working through he learn you a Haskell book and it said I should always use spaces.
The book itself seems to use 4 spaces in definition with guards though.
For example this function:
replicate' :: (Num i, Ord i) => i -> a -> [a]
replicate' n x
| n <= 0 = []
| otherwise = x:replicate' (n-1) x
When I replace the 4 spaces/tabs with a single space I get an indentation / missed brackets error in the otherwise case.
However, if I use a tab or 4 spaces this works.
Did I misunderstand something about using spaces over tabs? Should it be 4 spaces each time?
Because often 1 space does work, just with guards ghci is almost always (infuriatingly not always) complaining here.
I'm using sublime btw, in case there is an issue there.
Thanks a lot in advance.
For example:
maximum' [] = error "maximum of empty list"
maximum' [x] = x
maximum' (x:xs)
| x > maxTail = x
| otherwise = maxTail
where maxTail = maximum' xs
throws an indentation error
It sounds like the OP's actual problem was a weird state in a particular file, but I thought I'd provide an answer to the general question here.
Most parts of Haskell syntax are completely insensitive to indentation (most of the common practices about laying out Haskell code are stylistic, rather than necessary). For example, all of these ways of writing the last equation in the OP's example work just fine:
-- guards indented more than where
maximum' (x:xs)
| x > maxTail = x
| otherwise = maxTail
where maxTail = maximum' xs
-- where indented more than guards
maximum' (x:xs)
| x > maxTail = x
| otherwise = maxTail
where maxTail = maximum' xs
-- all on one line, no indentation at all!
maximum' (x:xs) | x > maxTail = x | otherwise = maxTail where maxTail = maximum' xs
Even something horrifying like this works:
-- please, no
maximum' (x:xs) |
x
> maxTail = x
| otherwise
= maxTail where
maxTail
= maximum' xs
There are exactly 2 things you can to do mess up indentation in the code shown:
Use more than one line to define the equation, with any of the continuation lines not starting with at least one whitespace character
Use more than one line to define the where clause, with any of the continuation lines starting at a character position less than that of the first character after the where keywords (i.e. the m in maxTail)
Otherwise, the whitespace in this example does not matter at all (apart from separating identifiers and keywords).
There is basically only one general way in which indentation matters in Haskell. And it's actually not indentation as such, but alignment that matters. That happens in the context of "blocks" containing a variable number of entries:
a let <decls> in <expr> expression contains 1 or more declarations in the <decls> part
a where clause introduces 1 or more declarations
an instance definition's where part has zero or more method definitions
a do block has 1 or more statements
a case expression has 1 or more cases (zero or more with the EmptyCase extension)
etc, etc
The variable number of entries in these blocks are the only places where alignment matters. There is always a keyword introducing the block, and the character position of the first entry in the block sets the alignment; after that every line that starts exactly at this character position is taken as the beginning of the next entry in the block, every line that starts past this position is taken as a continuation line of the previous entry, and the first line that starts before alignment position is taken as ending the block (and the contents of this line are not part of the block). Sometimes there is also a keyword that will indicate the end of the block, regardless of any indentation (e.g. the in part of let <decls> in <expr> is indicated by the in keyword even if it's on the same line as part or all of the <decls>).
As an aside, you may at this point be wondering why it's possible to get an error with code like this:
bar x y
= x + y
I haven't used any where, let, etc blocks above, but it's possible to get an alignment error here by continuing the bar definition onto a new line without indentation? Didn't I promise indentation only matters in blocks? Well, actually the entire global scope of a module is an aligned block! We just usually don't notice it because it's conventional to use alignment position 0 for this block. But technically, that's what's going on (thus you can't have a continuation line for one of the declarations in the global block that starts at alignment 0).
This layout based on alignment rather than indentation is why tabs are often considered difficult to use to layout Haskell code. As an example, consider this:
foo x y z = xy + yz
where xy = x * y
yz = y * z
Here I have used 4 spaces to indent the where part, and this is one of those places where the whitespace is completely irrelevant, so I could have used anything I like. Therefore, if I'm accustomed to using tabs as indentation in other programming languages, I might have been tempted to use a tab rather than 4 spaces.
Where things get nasty is that the correct indentation of the yx = y * z line is not "2 indent levels in", but rather "lining up exactly with the xy = x * y definition". So if I had used a tab to indent the where, the only correct way to indent the following line is to use a tab followed by 6 spaces. In my experience this is something that even smart formatting code editors never get right (let alone humans doing it manually); it is far more likely that if my view settings have a tab take up less space than the where keyword (such as the common 4 spaces) that I will get at least 2 leading tabs, followed by enough spaces to make the yz = y * z line appear to line up with the definition above.
Haskell compilers, by the spec, treat tab stops as eight spaces apart. So the situation I described above (where the first definition in the where is at 1 tab plus 6 normal characters and the second is at 2 tabs plus 2 normal characters) results in an invisible error. The compiler thinks these definitions are at positions 14 and 18, but to me they look the same. This sort problem is not fun. Hence the upvoted comment "When to use tabs? Never! That was an easy one."
Technically you can set your editor to show tabs stops at 8 spaces, and then it doesn't matter whether a given amount of indentation is all spaces or any mix of tabs and spaces that looks the same. However, most people don't like to have their editor set to show tabs as 8 spaces, and fixing any particular number defeats the entire point of indenting using tabs (having the visual appearance of "indent levels" be something that each user can configure independently in their editor).
It is also possible to adopt a code style that avoids the problem. Basically: always end the line immediately after a keyword introducing a block, so that the block starts on a new line (which you bump up the next indent level). You would then write (for the OP's example):
maximum' (x:xs)
| x > maxTail = x
| otherwise = maxTail
where
maxTail = maximum' xs
If you do that then your alignment positions will always be an exact number of tabs and zero normal characters, so you will not end up forced to use leading space that is a mix of tabs and spaces. In fact Haskell's alignment rules become extremely similar to Python's indentation rules if you code like this (the major reason they are different is that Haskell allows you to start an aligned block on the same line as preceding code, whereas Python's blocks are always preceded by a line ending in a colon).
But by far the most common approach to using tabs in Haskell is: simply don't do it. Configure your editor to insert spaces up to the next "tab-stop" when you press the tab key, if you like. But make sure the physical source code file is saved with spaces.
Gratuitous soapbox time!
For me personally, the reasoning above is why I don't like to use tabs in any language. Because sooner or later someone always ends up wanting to make something on one line visually align with something on another line, and this often needs indentation that is a mix of tabs and spaces. The tab and space mix is almost never correctly handled by the editor (to do so in general requires the editor to be able to tell when a line is a continuation line or the start of a new syntactic construct, before the coder has finished typing it, which is at best language-dependent and at-worst just impossible). So they write code that is simply incorrectly formatted as soon as someone uses a different tab-width preference than they used.
An example would be this fairly common layout (in no particular language):
class Foo {
public int foo(int x, char y, long listOfParameters,
bool z, double ooopsRanOutOfLetters) {
codeStartsHere();
If indent levels are tabs, then the correct indentation for the continuation of the parameter list is 1 tab and 15 spaces, but someone is just as likely to get 4 tabs and 3 spaces, which throws off the alignment completely at any other tab-width setting. Basically, if indent levels are to be configured for each coder's preference (by setting the tab-width), then there is a fundamental difference between inserting an indent level and inserting a visually-equivalent number of spaces, requiring you to think about which you intend every time you hit the tab key. Even if the formatting is purely a visual aid to human readers and causes no change in how the compiler/interpreter will read the code, aiding human readers is arguably more important than merely writing something that the machine will accept.
And again, this problem can be addressed by rigidly adhering to a style guide that is carefully constructed to avoid layouts like the above ever happening. But I just don't want to have to think about that when I'm designing or evaluating a style guide, nor when I'm writing code. "Always indent with spaces" is an incredibly simple rule to put in a style guide, and then it's never an issue regardless of the other rules you adopt (and regardless of whether those other rules are strictly followed or there are exceptions).
Only use spaces, because Haskell is indentation-sensitive and implicit layout blocks must start on a column greater than their layout keywords, so it's important to keep track of columns exactly.
Furthermore, tab stops are 8 columns apart according to Haskell2010, which is huge by today's indentation standards which are usually at most 4 spaces.

What is parse error? how to remove it? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
In this Script,
approximation :: Int -> (String, Int)
approximation x
| (x<20000) && (19000<=x) && (numDigits<x) = (text1, x-numDigits)
| (x<20000) && (19000<=x) && (numDigits>x) = (text1, numDigits-x)
| (x<19800) && (x>=19700) && (numDigits<x) = (text2, x-numDigits)
| (x<19800) && (x>=19700) && (numDigits>x) = (text2, numDigits-x)
| otherwise = ("far from no. of Digits", 0)
where
text1 = "at 1000th place of no. of reallyBig, abosolute error="
text2 = "at 100th place of no. of reallyBig, nearly Exact, absolute error"
I inputted 2 definitions: text1, text2 for the Function approximation. However, the compiler GHCI said there is a Parse error on input '=' in text2. I was confused by the problem.
You have mixed tabs and spaces for your indentation. This is a bad plan, because your editor and ghc can think about tabs quite differently. I think your editor is displaying tabs as (up to) 4 characters, whereas ghc thinks of tabs as (up to) 8 spaces. I'll write <--> for a tab and . for a space in your last two lines:
<-->....text1 = "at 1000th place of no. of reallyBig, abosolute error="
<--><-->text2 = "at 100th place of no. of reallyBig, nearly Exact, absolute error"
Which is how your editor displays it. If I put ghc's 8 space tabs in, you get
<-------->....text1 = "at 1000th place of no. of reallyBig, abosolute error="
<--------><-------->text2 = "at 100th place of no. of reallyBig, nearly Exact, absolute error"
and you get the parse error.
It's easiest if you stick to spaces. Change your editor's settings.
If you use just spaces, you can't get this problem, because your editor has to show it the way the compiler thinks about it.
My editor lets me specify that when I press tab, it should insert the number of spaces that a tab would show as, so I use that, which is safe for a tabstop of 4. If your editor can do that, use that option. (If not, consider getting a cleverer editor for when you're programming.
My editor also has auto indent and outdent, where the next line copies the whitespace indentation of the previous line - this avoids the problem. Turn this on if your editor supports it, because it saves you effort and you're less likely to get the parse error. (When I then press backspace, my editor deletes back to the previous level of indentation, which is nice.)
Almost all editors can change how they display tabs. If you can't get it to use spaces for tabs, you should change the tabstop to be 8, because that matches ghc, and you're much less likely to get this error, but you're still better off using spaces.

Cannot enter multiline statements in GHCi [duplicate]

This question already has answers here:
Multi-line commands in GHCi
(5 answers)
Closed 9 years ago.
let x=1
y=2
z=3
does not work in GHCi, forcing me to use let {x=1;y=2;y=3} instead. How can I fix this problem?
The documentation says:
GHCi also has a multiline mode, enabled by :set +m, in which GHCi detects automatically when the current statement is unfinished and allows further lines to be added. A multi-line input is terminated with an empty line.
The multiline mode makes GHCi behave much like e.g. the Python interpreter:
Prelude> :set +m
Prelude> let x = 1
Prelude| y = 2
Prelude| z = 3
Prelude|
Prelude> (x, y, z)
(1,2,3)
This hidden gem is wonderful for playing with readable code!
If you want this to be the default behaviour, you can create a .ghci file in your home directory with a line saying :set +m. (Now that this came up, I actually did so.)

vim fold text with spaces in front

I'm trying to customize vim folding style and stuck with indentation. I know it has been asked multiple times here and I use this command (which seem to work for others) to test the appearance of fold:
:set foldtext=' '.foldtext()
This however gives me 'unknown option' error. Apparently, it doesn't accept the string containing only space(s), because this
:set foldtext='mytext'.foldtext()
works fine and adds 'mytext' to the beginning of folds.
Why doesn't it work and what's the way around it?
You just need to escape the space. Use this instead.
:set foldtext='\ '.foldtext()
The space is causing vim to think you want to set foldtext to ' and then '.foldtext() is the next argument to set. However this isn't what you want and the reason the error message is
E518: Unknown option: '.foldtext()
Escaping the space tell vim that foldtext='\ '.foldtext() is one argument instead of two.
You can use the EightHeader plugin if you prefer aligned foldtext. Example from the help:
If you don't like the default 'foldtext' you can customize it by setting to
EightHeaderFolds().
For example the closed folds looks like this by default:
```+-- 45 lines: Fold level one
+--- 67 lines: Fold level two
If you would like to change it to this kind:
Fold level one................45 lines
Fold level two..............67 lines
... then you can use this function:
let &foldtext = "EightHeaderFolds( '\\=s:fullwidth-2', 'left', [ repeat( ' ', v:foldlevel - 1 ), '.', '' ], '\\= s:foldlines . \" lines\"', '' )"

Haskell indentation error [duplicate]

This question already has an answer here:
Why shouldn't I mix tabs and spaces?
(1 answer)
Closed 6 years ago.
Why is the following code not correct ? i get this error: Last generator in do {...} must be an expression?
main = do putStrLn "What is 2 + 2?"
x <- readLn
if x == 4
then putStrLn "You're right!"
else putStrLn "You're wrong!"
You are mixing tabs and spaces: the second and fifth line contain tabs, while the third and fourth don't.
The Haskell compiler probably expands tabs to a different number of spaces than your editor and what looks correctly indented in the editor looks messed up to the compiler.
Best avoid mixing tabs and spaces and only use one of them for indentation.
You had tabulations instead of spaces. After you have pasted the code into stackoverflow there are only spaces and everything is working.

Resources