I am trying to recreate the output of this Haskell code:
forM_ = flip mapM_
import Control.Monad.Cont
main = do
forM_ [1..3] $ \i -> do
print i
forM_ [7..9] $ \j -> do
print j
withBreak $ \break ->
forM_ [1..] $ \_ -> do
p "loop"
break ()
where
withBreak = (`runContT` return) . callCC
p = liftIO . putStrLn
The expected output is as follows:
$ runhaskell for.hs
1
2
3
7
8
9
loop
But I am getting the following error:
Test4.hs:2:1: parse error on input `import'
Any ideas about what is going wrong?
Test4.hs:2:1: parse error on input `import'
The error points to the second line of your file. Quoting the first two lines:
forM_ = flip mapM_
import Control.Monad.Cont
The problem is that an import declaration must be at the beginning of a module, before any definitions (the only things that can come before an import are language pragmas, such as those used to enable GHC extensions, and the module declaration). In your case, the first line of the file is a definition, and so the misplaced import declaration in the second line leads to a parse error. Since that first line wasn't actually part of the code snippet in the post you linked to, you can simply delete it.
Related
This question already has an answer here:
GHCi and compiled code seem to behave differently
(1 answer)
Closed 1 year ago.
Today I want Haskell to behave like any imperative language, look at this:
import Data.HashMap.Strict as HashMap
import Data.Text.IO
import Data.Text
import Data.Functor ((<&>))
putStr "Reading data from file ..."
ls <- lines <$> readFile myFile
putStrLn " done."
putStr "Processing data ..."
let hmap = HashMap.fromList $ ls <&> \l -> case splitOn " " l of
[k, v] -> (k, v)
_ -> error "expecting \"key value\""
putStrLn " done."
Basically, the user should know what the program is doing at the moment. The result of this code is the immediate output of
> Reading data from file ... done.
> Sorting data ... done.
... and then it starts doing the actual work, the output defeating its purpose.
I am well aware that it's a feature. Haskell is declarative and order of evaluation is determined by actual dependencies, not by line numbers in my .hs-file. Thus I try the following approach:
putStr "Reading data from file ..."
lines <- lines <$> readFile myFile
putStrLn $ lines `seq` " done."
putStr "Processing data ..."
let hmap = HashMap.fromList $ ls <&> \l -> case splitOn " " l of
[k, v] -> (k, v)
_ -> error "expecting \"key value\""
putStrLn $ hmap `seq` " done."
The idea: seq only returns once its first argument has been evaluated to Weak Head Normal Form. And it works, kind of. The output of my program is now nothing for a while and then, once the work as been done, all the IO occurs.
Is there a way out of this?
EDIT: I changed the question in reply to Ben's answer. The imports should now make more sense and the program really runs.
DanielWagner commented about this related question:
GHCi and compiled code seem to behave differently
which indeed solves my problem.
putStrLn $ hmap `seq` " done."
does exactly what it's supposed to. I am only missing flushing stdout. So this actually does what I need:
putStr "Reading data from file ..."
hFlush stdout -- from System.IO
lines <- lines <$> readFile myFile
putStrLn $ lines `seq` " done."
putStr "Processing data ..."
hFlush stdout
let hmap = HashMap.fromList $ ls <&> \l -> case splitOn " " l of
[k, v] -> (k, v)
_ -> error "expecting \"key value\""
putStrLn $ hmap `seq` " done."
You haven't given us the actual code that you say has this behaviour:
The output of my program is now nothing for a while and then, once the work as been done, all the IO occurs.
How do I know it's not the code you're running? Your code doesn't compile in order to be run at all! A few problems:
You get a type error from lines, because it's in the standard Prelude but that version works on String, and you're working with Text.
You haven't imported splitOn from anywhere
The obvious splitOn to import is from Data.Text, but that has type Text -> Text -> [Text] i.e. it returns a list of Text splitting at all occurrences of the separator. You're obviously expecting a pair, splitting only on the first separator.
So at the very minimum this is code you were running in ghci after more imports/definitions that you haven't shown us.
Changing it as little as I could and get it to run gave me this:
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.HashMap.Strict as HashMap
import qualified Data.Text.IO as StrictIO
import qualified Data.Text as Text
myFile = "data.txt"
main = do
putStr "Reading data from file ..."
lines <- Text.lines <$> StrictIO.readFile myFile
putStrLn $ lines `seq` " done."
putStr "Processing data ..."
let hmap = HashMap.fromList $ Text.breakOn " " <$> lines
putStrLn $ hmap `seq` " done."
I generated a very simple data file with 5,000,000 lines and ran the program with runhaskell foo.hs, and there are in fact noticeable pauses between the appearance of the reading/processing messages and the "done" appearing on each line.
I see no reason why all of the IO would be delayed appear at once (including the result of the first putStrLn. How are you actually running this code (or rather, the full and/or different code that actually runs)? In the post you've written it as input for GHCi rather than a full program (judging by the imports and IO statements at the same level, with no do block or definition of any top level functions). The only thought I had is that perhaps your data file is much smaller such that the processing takes a barely perceptible amount of time, and the initial startup processing of the Haskell code itself by ghci or runhaskell is the only noticeable delay; then I can imagine there being a slight delay followed by the printing of all the messages seemingly at once.
This question already has an answer here:
How to use variable from do block assignment line in a where clause?
(1 answer)
Closed 2 years ago.
I was making a program with Haskell and it's IO, when I came across an error I don't understand. When I use a where statement after a do block it does not do the same thing as without the do block.
The program that works is:
import Control.Monad
prog :: IO()
prog = do m <- getLine
n <- getLine
p <- getLine
replicateM_ (read m :: Int) (putStrLn n)
replicateM_ (read m :: Int) (putStrLn p)
But when I replace the read m :: Int with a where statement like this:
import Control.Monad
prog1 :: IO()
prog1 = do m <- getLine
n <- getLine
p <- getLine
replicateM_ (a) (putStrLn n)
replicateM_ (a) (putStrLn p)
where
a = read m :: Int
I get the error:
Template.hs:23:21: error: Variable not in scope: m :: String
|
23 | a = read m :: Int
| ^
I have looked what the problem could be, and I think it has to do with the type of m, which is IO String. I know you have to stay in the IO type (once you are in it) to be able to work with the string. But I don't understand why the 'where' would "break out" of this IO type. To my understanding the two examples I gave are functional the same. First I thought that the error wouldn't be fixed by writing the program without the where, because the function read is from the type read :: Read a => String -> a and my input in the first program is also IO String. So why didn't my first program give me an error? Could someone explain what I understand wrong and how I can fix my program so I only have to execute read m :: Int once? Just some tips of how to use a where statement under a do block would also help.
The original program I got the problem in is longer and not all relevant so I used this minimal working example to explain the essence of my question. In my original program I have multiple statements after where, so I don't want to substitute it all like I did in this example.
The bindings in the do block are opaque to the where statement after it, so you can't reference anything defined in the do block inside the where statement. You don't need to either, since you can use let directly inside do:
prog1 = do m <- getLine
n <- getLine
p <- getLine
-- alternatively: [m, n, p] <- replicateM 3 getLine
-- use a let statement
let a = read m :: Int
replicateM_ a (putStrLn n)
replicateM_ a (putStrLn p)
I am trying to write a simple program that reads a line from standard input, reverses it, and then prints the reversed string.
Unfortunately the native getLine function reads a Costring; I can only reverse Strings; and there is no function that takes a Costring to a String.
How can I amend this program to compile?
module EchoInputReverse where
-- Agda standard library 0.7
open import Data.List using (reverse)
open import Data.String
open import Foreign.Haskell using (Unit)
open import IO.Primitive
postulate
getLine : IO Costring
{-# COMPILED getLine getLine #-}
main : IO Unit
main =
getLine >>= (λ s →
-- NOTE: Need a (toString : Costring → String) here. Or some other strategy.
return (toCostring (fromList (reverse (toList (toString s))))) >>= (λ s' →
putStrLn s'))
You can't do that, at least not directly. The problem is that Costring can be infinite in size, while Strings must be finite.
Imagine running the program as prog < /dev/zero, what should happen? The reverse function can produce the first element only after reaching the end of the input list and that may never happen.
We need to express the fact that converting a Costring to String can fail. One way to do it is to use the partiality monad. Let's take a look at the definition:
data _⊥ {a} (A : Set a) : Set a where
now : (x : A) → A ⊥
later : (x : ∞ (A ⊥)) → A ⊥
So, we can either have a value of type A right now, or we need to wait for later. But notice the ∞ symbol: that means we can actually wait forever (as in there can be infinite number of later constructors).
I'll merge the conversion and reversing into one function. Imports first:
open import Category.Monad.Partiality
open import Coinduction
open import Data.Char
open import Data.Colist
using ([]; _∷_)
open import Data.List
using ([]; _∷_; List)
open import Data.String
open import Data.Unit
open import IO
Now, the type of our reverse function should mention that we take a Costring as an input but also that returning a String may fail. The implementation is then fairly simple, it's the usual reverse with accumulator:
reverse : Costring → String ⊥
reverse = go []
where
go : List Char → Costring → String ⊥
go acc [] = now (fromList acc)
go acc (x ∷ xs) = later (♯ go (x ∷ acc) (♭ xs))
However, we can print a String, but not String ⊥! That's where IO helps: we can interpret the later constructors as "do nothing" and if we find now constructor, we can putStrLn the String it contains.
putStrLn⊥ : String ⊥ → IO ⊤
putStrLn⊥ (now s) = putStrLn s
putStrLn⊥ (later s) = ♯ return tt >> ♯ putStrLn⊥ (♭ s)
Notice that I use the IO from IO module, not the one from IO.Primitive. This is basically a layer built on the postulates, so it's a bit nicer. But if you want to use getLine with this, you have to write:
import IO.Primitive as Prim
postulate
primGetLine : Prim.IO Costring
{-# COMPILED primGetLine getLine #-}
getLine : IO Costring
getLine = lift primGetLine
And finally, we can write the main function:
main = run (♯ getLine >>= λ c → ♯ putStrLn⊥ (reverse c))
Compiling this program using C-c C-x C-c and then running it, we get the expected:
$ cat test
hello world
$ prog < test
dlrow olleh
Saizan on #agda points out that one could just postulate that getLine : IO String instead of getLine : IO Costring. This works. So you get:
module EchoInputReverse where
-- Agda standard library 0.7
open import Data.List using (reverse)
open import Data.String
open import Foreign.Haskell using (Unit)
open import IO.Primitive
postulate
getLine : IO String
{-# COMPILED getLine getLine #-}
main : IO Unit
main =
getLine >>= (λ s →
return (toCostring (fromList (reverse (toList s)))) >>= (λ s' →
putStrLn s'))
The downside is that this approach asserts that getLine always returns a finite string, which may not be correct in the case of prog < /dev/zero as #Vitus points out.
But I don't think this matters. If getLine does in fact returns an infinite string then neither this solution nor #Vitus's solution will yield a program that terminates. They have equivalent behavior.
It would be ideal to detect whether the input was infinite and yield an error in that case. But this kind of infinity detection on IO is not possible in general.
I have a program in haskell that has to read arbitrary lines of input from the user and when the user is finished the accumulated input has to be sent to a function.
In an imperative programming language this would look like this:
content = ''
while True:
line = readLine()
if line == 'q':
break
content += line
func(content)
I find this incredibly difficult to do in haskell so I would like to know if there's an haskell equivalent.
The Haskell equivalent to iteration is recursion. You would also need to work in the IO monad, if you have to read lines of input. The general picture is:
import Control.Monad
main = do
line <- getLine
unless (line == "q") $ do
-- process line
main
If you just want to accumulate all read lines in content, you don't have to do that. Just use getContents which will retrieve (lazily) all user input. Just stop when you see the 'q'. In quite idiomatic Haskell, all reading could be done in a single line of code:
main = mapM_ process . takeWhile (/= "q") . lines =<< getContents
where process line = do -- whatever you like, e.g.
putStrLn line
If you read the first line of code from right to left, it says:
get everything that the user will provide as input (never fear, this is lazy);
split it in lines as it comes;
only take lines as long as they're not equal to "q", stop when you see such a line;
and call process for each line.
If you didn't figure it out already, you need to read carefully a Haskell tutorial!
It's reasonably simple in Haskell. The trickiest part is that you want to accumulate the sequence of user inputs. In an imperative language you use a loop to do this, whereas in Haskell the canonical way is to use a recursive helper function. It would look something like this:
getUserLines :: IO String -- optional type signature
getUserLines = go ""
where go contents = do
line <- getLine
if line == "q"
then return contents
else go (contents ++ line ++ "\n") -- add a newline
This is actually a definition of an IO action which returns a String. Since it is an IO action, you access the returned string using the <- syntax rather than the = assignment syntax. If you want a quick overview, I recommend reading The IO Monad For People Who Simply Don't Care.
You can use this function at the GHCI prompt like this
>>> str <- getUserLines
Hello<Enter> -- user input
World<Enter> -- user input
q<Enter> -- user input
>>> putStrLn str
Hello -- program output
World -- program output
Using pipes-4.0, which is coming out this weekend:
import Pipes
import qualified Pipes.Prelude as P
f :: [String] -> IO ()
f = ??
main = do
contents <- P.toListM (P.stdinLn >-> P.takeWhile (/= "q"))
f contents
That loads all the lines into memory. However, you can also process each line as it is being generated, too:
f :: String -> IO ()
main = runEffect $
for (P.stdinLn >-> P.takeWhile (/= "q")) $ \str -> do
lift (f str)
That will stream the input and never load more than one line into memory.
You could do something like
import Control.Applicative ((<$>))
input <- unlines . takeWhile (/= "q") . lines <$> getContents
Then input would be what the user wrote up until (but not including) the q.
I've defined a lot of functions (say, 100+), each of which do a specific work but with the same signature. That is something like:
module R001 (run) where run = <do-...>
module R002 (run) where run = <do-...>
What I wanna do is to provide the actual 'run' as user input, such that:
main = do
runWith $ read $ getLine
where
runWith :: Int -> IO ()
runWith n = R<n-padded-with-0>.run
Currently, I import all modules qualified, and put all the run's into a list of [Maybe (IO())], so this works:
runWith n = case Rs !! (read $ getLine) of
Just run -> run
Nothing -> undefined
But as the n grows, I have to continously maintain a big list.
Is there any way I can define the big list using TemplateHaskell, or just load the corresponding module as needed at runtime without having to seperate each module into different shared libraries.
Based on epsilonhalbe's answer, I did some research:
import R1 (run1)
import R2 (run2)
test = $(functionExtractor "^run")
main :: IO ()
main = do
putStrLn $ show $ length $ test
run1 -- remove on second attempt
run2 -- remove on second attempt
This block of code prints 2 following the results of run1 and run2. If I remove the last two lines, it just prints 0. It seems that functions imported but not referenced won't be extracted ...
I once had a similar problem haskell load module in list maybe this helps.
You can create a list of functions with regexp and choose a function by userinput from that list.
I don't know if you have to import all "runs" qualified by hand or if you can
import R*.hs (run)
i would rather write one file with run1 = …, run2 = … and generate a list of all runs and a function chooser function which takes a function from a list of functions with the same type signature.
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.Extract
import myRunFunctions
main = do
let listOfRuns = $(functionExtractor "^run")
putStrLn "please choose a run"
putStrLn $ show listOfRuns
let run = runWith $ read $ getLine
run
where
runWith n = listOfRuns !! n
Attention: I have not run this code this is just a stream of thought put in haskell syntax
i hope this is helpful
After edit:
In my example i wrote all run* in one file and there i generated the list of all run functions, which worked instantly - have a look at my Nucleotide Project especially the files Rules.hs and Nucleotide.hs.
Runs.hs
module Runs where
import Language.Haskell.Extract
listOfRuns = map snd $(functionExtractor "^run")
run1 = …
run2 = …
Main.hs
import Runs
main = do
putStrLn "please choose a run"
putStrLn $ show listOfRuns
let run = runWith $ read $ getLine
run
where
runWith n = listOfRuns !! n
happy to be helpful
Is it absolutely critical that the different run functions live in different modules? If you can put them all in one module, you could make run be a function of an Int (or Integer if you prefer).
module AllMyCircuits where
run 0 = {- do blah blah blah -}
run 1 = {- do blah blah blah -}
run 2 = {- do yikes -}
module Main where
import AllMyCircuits
main = readLn >>= run