Input length restriction in GHCi - haskell

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!

Related

Haskell function that takes input as a String and returns same sequence of characters in reverse order

The issue is, I am doing:
reverse ("Hello how are you")
and getting output as: "uoy era woh olleh"
but the expected output is: uoy era woh olleh
Not sure how to remove quotes(") from the above string.
I assume you're referring to this:
GHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/sagemuej/.ghci
Loaded GHCi configuration from /home/sagemuej/.ghc/ghci.conf
Prelude> reverse "Hello how are you"
"uoy era woh olleH"
...when actually you would like to have the reply without any quotes around it. Well, GHCi passes all evaluation results through print, which in turn uses the Show typeclass to transform any value into a string – notably, a string that's valid Haskell source code, and could as such be used to recreate the value. (That's extremely useful in prototyping, and it's not limited to strings but can also handle all sorts of other types.)
Now, "uoy era woh olleH" clearly is valid Haskell source code
Prelude> "uoy era woh olleH"
"uoy era woh olleH"
but without the quotes it wouldn't be:
Prelude> uoy era woh olleH
<interactive>:3:1: error:
Variable not in scope: uoy :: t0 -> t1 -> t2 -> t
<interactive>:3:5: error: Variable not in scope: era
<interactive>:3:9: error: Variable not in scope: woh
<interactive>:3:13: error: Variable not in scope: olleH
that's why GHCi does this. But if you don't want to use the reply as Haskell code, then you also don't need the show wrapper. To just print the raw content of strings, you'll need to explicitly use the IO action whose purpose this is: putStrLn
Prelude> putStrLn $ reverse "Hello how are you"
uoy era woh olleH
(If you don't know what $ is yet: read it as a shorthand notation for putStrLn (reverse "Hello how are you").)

Haskell error: parse error on input '='

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.

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.

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).

Haskell read first n lines

I'm trying to learn Haskell to get used to functional programming languages. I've decided to try a few problems at interviewstreet to start out. I'm having trouble reading from stdin and doing io in general with haskell's lazy io.
Most of the problems have data coming from stdin in the following form:
n
data line 1
data line 2
data line 3
...
data line n
where n is the number of following lines coming from stdin and the next lines are the data.
How do I run my program on each of the n lines one at a time and return the solution to stdout?
I know the stdin input won't be very large but I'm asking about evaluating each line one at a time pretending the input is larger than what can fit in memory just to learn how to use haskell.
You can use interact, in conjunction with lines to process data from stdin one line at a time. Here's an example program that uses interact to access stdin, lines to split the data on each newline, a list comprehension to apply the function perLine to each line of the input, and unlines to put the output from perLine back together again.
main = interact processInput
processInput input = unlines [perLine line | line <- lines input]
perLine line = reverse line -- do whatever you want to 'line' here!
You don't need to worry about the size of the data you're getting over stdin; Haskell's laziness ensures that you only keep the parts you're actually working on in memory at any time.
EDIT: if you still want to work on only the first n lines, you can use the take function in the above example, like this:
processInput input = unlines [perLine line | line <- take 10 (lines input)]
This will terminate the program after the first ten lines have been read and processed.
You can also use a simple recursion:
getMultipleLines :: Int -> IO [String]
getMultipleLines n
| n <= 0 = return []
| otherwise = do
x <- getLine
xs <- getMultipleLines (n-1)
return (x:xs)
And then use it in your main:
main :: IO ()
main = do
line <- getLine
let numLines = read line :: Int
inputs <- getMultipleLines numLines

Resources