Haskell error: parse error on input '=' - haskell
I created a new quick.hs file in the ghci.exe directory. And the content is
quicksort::(Ord a)=>[a]->[a]
quicksort []=[]
quicksort (x:xs)=
let smaller = [a |a<-xs,a<=x]
larger = [a |a<-xs,a>x]
in quicksort smaller ++ [x] ++ quicksort larger
When I issue :l quick in the ghci command lline, the output is
Prelude> :l quick
[1 of 1] Compiling Main ( quick.hs, interpreted )
quick.hs:5:17: error:
parse error on input ‘=’
Perhaps you need a 'let' in a 'do' block?
e.g. 'let x = 5' instead of 'x = 5'
Failed, modules loaded: none.
I have concured this kind of problems many times. What's wrong on earth?
You say in the comments that you are sure there are no tab characters in the source file, but inspecting the source of your question, indeed there is one right before the in token. Replace that with the appropriate number of spaces and you'll be all good.
You have to remove all tabs and change it by spaces. I hope that this instruction helps you.
Related
Is there a (Template) Haskell library that would allow me to print/dump a few local bindings with their respective names?
For instance: let x = 1 in putStrLn [dump|x, x+1|] would print something like x=1, (x+1)=2 And even if there isn't anything like this currently, would it be possible to write something similar?
TL;DR There is this package which contains a complete solution. install it via cabal install dump and/or read the source code Example usage: {-# LANGUAGE QuasiQuotes #-} import Debug.Dump main = print [d|a, a+1, map (+a) [1..3]|] where a = 2 which prints: (a) = 2 (a+1) = 3 (map (+a) [1..3]) = [3,4,5] by turnint this String "a, a+1, map (+a) [1..3]" into this expression ( "(a) = " ++ show (a) ++ "\t " ++ "(a+1) = " ++ show (a + 1) ++ "\t " ++ "(map (+a) [1..3]) = " ++ show (map (+ a) [1 .. 3]) ) Background Basically, I found that there are two ways to solve this problem: Exp -> String The bottleneck here is pretty-printing haskell source code from Exp and cumbersome syntax upon usage. String -> Exp The bottleneck here is parsing haskell to Exp. Exp -> String I started out with what #kqr put together, and tried to write a parser to turn this ["GHC.Classes.not x_1627412787 = False","x_1627412787 = True","x_1627412787 GHC.Classes.== GHC.Types.True = True"] into this ["not x = False","x = True","x == True = True"] But after trying for a day, my parsec-debugging-skills have proven insufficient to date, so instead I went with a simple regular expression: simplify :: String -> String simplify s = subRegex (mkRegex "_[0-9]+|([a-zA-Z]+\\.)+") s "" For most cases, the output is greatly improved. However, I suspect this to likely mistakenly remove things it shouldn't. For example: $(dump [|(elem 'a' "a.b.c", True)|]) Would likely return: ["elem 'a' \"c\" = True","True = True"] But this could be solved with proper parsing. Here is the version that works with the regex-aided simplification: https://github.com/Wizek/kqr-stackoverflow/blob/master/Th.hs Here is a list of downsides / unresolved issues I've found with the Exp -> String solution: As far as I know, not using Quasi Quotation requires cumbersome syntax upon usage, like: $(d [|(a, b)|]) -- as opposed to the more succinct [d|a, b|]. If you know a way to simplify this, please do tell! As far as I know, [||] needs to contain fully valid Haskell, which pretty much necessitates the use of a tuple inside further exacerbating the syntactic situation. There is some upside to this too, however: at least we don't need to scratch our had where to split the expressions since GHC does that for us. For some reason, the tuple only seemed to accept Booleans. Weird, I suspect this should be possible to fix somehow. Pretty pretty-printing Exp is not very straight-forward. A more complete solution does require a parser after all. Printing an AST scrubs the original formatting for a more uniform looks. I hoped to preserve the expressions letter-by-letter in the output. The deal-breaker was the syntactic over-head. I knew I could get to a simpler solution like [d|a, a+1|] because I have seen that API provided in other packages. I was trying to remember where I saw that syntax. What is the name...? String -> Exp Quasi Quotation is the name, I remember! I remembered seeing packages with heredocs and interpolated strings, like: string = [qq|The quick {"brown"} $f {"jumps " ++ o} the $num ...|] where f = "fox"; o = "over"; num = 3 Which, as far as I knew, during compile-time, turns into string = "The quick " ++ "brown" ++ " " ++ $f ++ "jumps " ++ o ++ " the" ++ show num ++ " ..." where f = "fox"; o = "over"; num = 3 And I thought to myself: if they can do it, I should be able to do it too! A bit of digging in their source code revealed the QuasiQuoter type. data QuasiQuoter = QuasiQuoter {quoteExp :: String -> Q Exp} Bingo, this is what I want! Give me the source code as string! Ideally, I wouldn't mind returning string either, but maybe this will work. At this point I still know quite little about Q Exp. After all, in theory, I would just need to split the string on commas, map over it, duplicate the elements so that first part stays string and the second part becomes Haskell source code, which is passed to show. Turning this: [d|a+1|] into this: "a+1" ++ " = " ++ show (a+1) Sounds easy, right? Well, it turns out that even though GHC most obviously is capable to parse haskell source code, it doesn't expose that function. Or not in any way we know of. I find it strange that we need a third-party package (which thankfully there is at least one called haskell-src-meta) to parse haskell source code for meta programming. Looks to me such an obvious duplication of logic, and potential source of mismatch -- resulting in bugs. Reluctantly, I started looking into it. After all, if it is good enough for the interpolated-string folks (those packaged did rely on haskell-src-meta) then maybe it will work okay for me too for the time being. And alas, it does contain the desired function: Language.Haskell.Meta.Parse.parseExp :: String -> Either String Exp Language.Haskell.Meta.Parse From this point it was rather straightforward, except for splitting on commas. Right now, I do a very simple split on all commas, but that doesn't account for this case: [d|(1, 2), 3|] Which fails unfortunatelly. To handle this, I begun writing a parsec parser (again) which turned out to be more difficult than anticipated (again). At this point, I am open to suggestions. Maybe you know of a simple parser that handles the different edge-cases? If so, tell me in a comment, please! I plan on resolving this issue with or without parsec. But for the most use-cases: it works. Update at 2015-06-20 Version 0.2.1 and later correctly parses expressions even if they contain commas inside them. Meaning [d|(1, 2), 3|] and similar expressions are now supported. You can install it via cabal install dump and/or read the source code Conclusion During the last week I've learnt quite a bit of Template Haskell and QuasiQuotation, cabal sandboxes, publishing a package to hackage, building haddock docs and publishing them, and some things about Haskell too. It's been fun. And perhaps most importantly, I now am able to use this tool for debugging and development, the absence of which has been bugging me for some time. Peace at last. Thank you #kqr, your engagement with my original question and attempt at solving it gave me enough spark and motivation to continue writing up a full solution.
I've actually almost solved the problem now. Not exactly what you imagined, but fairly close. Maybe someone else can use this as a basis for a better version. Either way, with {-# LANGUAGE TemplateHaskell, LambdaCase #-} import Language.Haskell.TH dump :: ExpQ -> ExpQ dump tuple = listE . map dumpExpr . getElems =<< tuple where getElems = \case { TupE xs -> xs; _ -> error "not a tuple in splice!" } dumpExpr exp = [| $(litE (stringL (pprint exp))) ++ " = " ++ show $(return exp)|] you get the ability to do something like λ> let x = True λ> print $(dump [|(not x, x, x == True)|]) ["GHC.Classes.not x_1627412787 = False","x_1627412787 = True","x_1627412787 GHC.Classes.== GHC.Types.True = True"] which is almost what you wanted. As you see, it's a problem that the pprint function includes module prefixes and such, which makes the result... less than ideally readable. I don't yet know of a fix for that, but other than that I think it is fairly usable. It's a bit syntactically heavy, but that is because it's using the regular [| quote syntax in Haskell. If one wanted to write their own quasiquoter, as you suggest, I'm pretty sure one would also have to re-implement parsing Haskell, which would suck a bit.
Input length restriction in GHCi
I programmed kakuro-solver, but I have problem with user's input. When user want to enter input longer then 1024 chars, haskell trims input and throws exception <interactive>:9:1024: parse error (possibly incorrect indentation or mismatched brackets) For example I want to enter this input kakuro [(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-1,0,6),(-1,0,23),(-2,0,0),(-2,0,0),(-1,0,7),(-1,0,23),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-1,0,18),(-1,0,12),(-2,0,0),(-1,0,12),(-1,0,26),(-1,9,0),(0,0,0),(0,0,0),(-2,0,0),(-1,13,19),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-1,7,23),(0,0,0),(0,0,0),(-1,3,0),(0,0,0),(0,0,0),(-1,5,16),(0,0,0),(0,0,0),(-1,18,10),(0,0,0),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-1,7,0),(0,0,0),(0,0,0),(0,0,0),(-1,10,0),(0,0,0),(0,0,0),(0,0,0),(-1,21,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-1,20,15),(0,0,0),(0,0,0),(0,0,0),(-1,24,0),(0,0,0),(0,0,0),(0,0,0),(-1,11,20),(0,0,0),(0,0,0),(0,0,0),(-1,0,17),(-2,0,0),(-2,0,0),(-1,14,0),(0,0,0),(0,0,0),(-1,0,23),(-1,0,12),(-1,0,15),(-1,20,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(-1,10,0),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-1,26,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(-1,0,13),(-2,0,0),(-1,13,19),(0,0,0),(0,0,0),(-1,13,0),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-1,33,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(-1,15,30),(0,0,0),(0,0,0),(-1,0,16),(-2,0,0),(-2,0,0),(-1,0,21),(-1,0,29),(-2,0,0),(-2,0,0),(-1,16,0),(0,0,0),(0,0,0),(-2,0,0),(-1,31,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(-1,0,12),(-1,17,13),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-1,0,11),(-1,0,23),(-2,0,0),(-1,10,37),(0,0,0),(0,0,0),(-1,26,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(-1,0,11),(-2,0,0),(-2,0,0),(-1,4,0),(0,0,0),(0,0,0),(-1,16,0),(0,0,0),(0,0,0),(-1,0,9),(-1,0,16),(-1,34,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-1,17,0),(0,0,0),(0,0,0),(-1,18,14),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(-1,0,13),(-2,0,0),(-1,0,20),(-1,4,13),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-1,0,7),(-1,18,21),(0,0,0),(0,0,0),(0,0,0),(-1,21,0),(0,0,0),(0,0,0),(0,0,0),(-1,22,0),(0,0,0),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-1,33,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(-1,6,17),(0,0,0),(0,0,0),(0,0,0),(-1,9,0),(0,0,0),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-1,8,0),(0,0,0),(0,0,0),(0,0,0),(-1,13,0),(0,0,0),(0,0,0),(-1,3,0),(0,0,0),(0,0,0),(-1,16,0),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-1,11,0),(0,0,0),(0,0,0),(-2,0,0),(-1,17,0),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0)] but WinGHCi trims it to kakuro [(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-1,0,6),(-1,0,23),(-2,0,0),(-2,0,0),(-1,0,7),(-1,0,23),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-1,0,18),(-1,0,12),(-2,0,0),(-1,0,12),(-1,0,26),(-1,9,0),(0,0,0),(0,0,0),(-2,0,0),(-1,13,19),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-1,7,23),(0,0,0),(0,0,0),(-1,3,0),(0,0,0),(0,0,0),(-1,5,16),(0,0,0),(0,0,0),(-1,18,10),(0,0,0),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-1,7,0),(0,0,0),(0,0,0),(0,0,0),(-1,10,0),(0,0,0),(0,0,0),(0,0,0),(-1,21,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-1,20,15),(0,0,0),(0,0,0),(0,0,0),(-1,24,0),(0,0,0),(0,0,0),(0,0,0),(-1,11,20),(0,0,0),(0,0,0),(0,0,0),(-1,0,17),(-2,0,0),(-2,0,0),(-1,14,0),(0,0,0),(0,0,0),(-1,0,23),(-1,0,12),(-1,0,15),(-1,20,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(-1,10,0),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-1,26,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(-1,0,13),(-2,0,0),(-1,13,19),(0,0,0),(0,0,0),(-1,13,0),(0,0,0),(0,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-1,33,0),(0,0,0) I tried use monad, but there is the same problem, I have to split input to more lines. Is there any options, how enter inputs longer then 1024 chars?
Sure: λ> :{ | let result = | kakuro [ | (-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0),(-2,0,0), | (-2,0,0),(-2,0,0),(-1,0,6),(-1,0,23) ... | -- AND SO ON... | ] | :} And then just evaluate result. However, I imagine that you've taken the list from the result of a previous command. In GHCi, the result of the previous expression is it, so you could probably write kakuro it. If you haven't done that, then read it from a file: λ> kakurodata <- read `fmap` readFile "/file/data/here.txt" λ> kakuro kakurodata EDIT: #Carsten pointed out that you could just plonk it in a file and :load it. Thanks!
Why complains Haskell parse error on input `|' in this Function?
I was supposed to write a little function in Haskell, which should erase elements, which are twice in the list. Unfortunately, Haskell complains " parse error on input `|' ". Could anyone help me with that? makeSets=mSet[]s where mSet stack []=stack mSet stack (x:xs) |contains stack x=mSetstack xs | otherwise =mSet (x:stack) xs where contains [] thing=False contains (x:xs)thing | x==thing=True |otherwise=contains xs thing
You are mixing tabs and spaces, which is no good when indentation is significant. Use either all spaces (strongly recommended), or all tabs.
Put result of code right below the code in resulting PDF. Haskell
Is there any way to execute code in a .lhs file and put the result right below the code itself in the resulting PDF? For example: [1,2,3] ++ [4,5,6] [1,2,3,4,5,6]
If you are using LaTeX, you can use lhs2TeX. Here is a simple example document: \documentclass{article} %include polycode.fmt %options ghci \begin{document} < [1,2,3] ++ [4,5,6] This evaluates to \eval{[1,2,3] ++ [4,5,6]}. > x = [1 .. 6] And this evaluates to \eval{x}, too. \end{document} This will run GHCi with the source file as input in the background. You can thus evaluate expressions using \eval in the context of the current (literate Haskell) module, and their results will be spliced into the resulting .tex sources.
I taught ghci to compile my StackOverflow posts. Can I make it slicker?
Haskell Stack Overflow layout preprocessor module StackOverflow where -- yes, the source of this post compiles as is Skip down to What to do to get it working if you want to play with this first (1/2 way down). Skip down to What I would like if I witter on a bit and you just want to find out what help I'm seeking. TLDR Question summary: Can I get ghci to add filename completion to the :so command I defined in my ghci.conf? Could I somehow define a ghci command that returns code for compilation instead of returning a ghci command, or does ghci instead have a better way for me to plug in Haskell code as a file-extension-specific pre-processor, so :l would work for .hs and .lhs files as usual, but use my handwritten preprocessor for .so files? Background: Haskell supports literate programming in .lhs source files, two ways: LaTeX style \begin{code} and \end{code}. Bird tracks: Code starts with > , anything else is a comment. There must be a blank line between code and comments (to stop trivial accidental misuse of >). Don't Bird tracks rules sound similar to StackOverflow's code blocks? References: 1. The .ghci manual 2. GHCi haskellwiki 3. Neil Mitchell blogs about :{ and :} in .ghci The preprocessor I like writing SO answers in a text editor, and I like to make a post that consists of code that works, but end up with comment blocks or >s that I have to edit out before posting, which is less fun. So, I wrote myself a pre-processor. If I've pasted some ghci stuff in as a code block, it usually starts with * or :. If the line is completely blank, I don't want it treated as code, because otherwise I get accidental code-next-to-comment-line errors because I can't see the 4 spaces I accidentally left on an otherwise blank line. If the preceeding line was not code, this line shouldn't be either, so we can cope with StackOverflow's use of indentation for text layout purposes outside code blocks. At first we don't know (I don't know) whether this line is code or text: dunnoNow :: [String] -> [String] dunnoNow [] = [] dunnoNow (line:lines) | all (==' ') line = line:dunnoNow lines -- next line could be either | otherwise = let (first4,therest) = splitAt 4 line in if first4 /=" " -- || null therest -- so the next line won't ever crash || head therest `elem` "*:" -- special chars that don't start lines of code. then line:knowNow False lines -- this isn't code, so the next line isn't either else ('>':line):knowNow True lines -- this is code, add > and the next line has to be too but if we know, we should keep in the same mode until we hit a blank line: knowNow :: Bool -> [String] -> [String] knowNow _ [] = [] knowNow itsCode (line:lines) | all (==' ') line = line:dunnoNow lines | otherwise = (if itsCode then '>':line else line):knowNow itsCode lines Getting ghci to use the preprocessor Now we can take a module name, preprocess that file, and tell ghci to load it: loadso :: String -> IO String loadso fn = fmap (unlines.dunnoNow.lines) (readFile $ fn++".so") -- so2bird each line >>= writeFile (fn++"_so.lhs") -- write to a new file >> return (":def! rso (\\_ -> return \":so "++ fn ++"\")\n:load "++fn++"_so.lhs") I've used silently redefining the :rso command becuase my previous attemts to use let currentStackOverflowFile = .... or currentStackOverflowFile <- return ... didn't get me anywhere. What to do to get it working Now I need to put it in my ghci.conf file, i.e. in appdata/ghc/ghci.conf as per the instructions :{ let dunnoNow [] = [] dunnoNow (line:lines) | all (==' ') line = line:dunnoNow lines -- next line could be either | otherwise = let (first4,therest) = splitAt 4 line in if first4 /=" " -- || null therest -- so the next line won't ever crash || head therest `elem` "*:" -- special chars that don't start lines of code. then line:knowNow False lines -- this isn't code, so the next line isn't either else ('>':line):knowNow True lines -- this is code, add > and the next line has to be too knowNow _ [] = [] knowNow itsCode (line:lines) | all (==' ') line = line:dunnoNow lines | otherwise = (if itsCode then '>':line else line):knowNow itsCode lines loadso fn = fmap (unlines.dunnoNow.lines) (readFile $ fn++".so") -- convert each line >>= writeFile (fn++"_so.lhs") -- write to a new file >> return (":def! rso (\\_ -> return \":so "++ fn ++"\")\n:load "++fn++"_so.lhs") :} :def so loadso Usage Now I can save this entire post in LiterateSo.so and do lovely things in ghci like *Prelude> :so StackOverflow [1 of 1] Compiling StackOverflow ( StackOverflow_so.lhs, interpreted ) Ok, modules loaded: StackOverflow. *StackOverflow> :rso [1 of 1] Compiling StackOverflow ( StackOverflow_so.lhs, interpreted ) Ok, modules loaded: StackOverflow. *StackOverflow> Hooray! What I would like: I would prefer to enable ghci to support this more directly. It would be nice to get rid of the intermediate .lhs file. Also, it seems ghci does filename completion starting at the shortest substring of :load that determines you're actually doing load, so using :lso instead of :so doesn't fool it. (I would not like to rewrite my code in C. I also would not like to recompile ghci from source.) TLDR Question reminder: Can I get ghci to add filename completion to the :so command I defined in my ghci.conf? Could I somehow define a ghci command that returns code for compilation instead of returning a ghci command, or does ghci instead have a better way for me to plug in Haskell code as a file-extension-specific pre-processor, so :l would work for .hs and .lhs files as usual, but use my handwritten preprocessor for .so files?
I would try to make a standalone preprocessor that runs SO preprocessing code or the standard literary preprocessor, depending on file extension. Then just use :set -pgmL SO-preprocessor in ghci.conf. For the standard literary preprocessor, run the unlit program, or use Distribution.Simple.PreProcess.Unlit. This way, :load and filename completion just work normally. GHCI passes 4 arguments to the preprocessor, in order: -h, the label, the source file name, and the destination file name. The preprocessor should read the source and write to the destination. The label is used to output #line pragmas. You can ignore it if you don't alter the line count of the source (i.e. replace "comment" lines with -- comments or blank lines).