I am trying to write a simple function which reads in one line at a time (which I know will be integers) and then stores them in to a list. For the life of me however, it seems like the list comes out to empty.
import System.IO
import Control.Monad
type Int2 = [Int]
valueTab = [] :: [Int]
app [ ] list = list
app (h:t) list = h:(app t list)
main :: IO ()
main = do
hSetBuffering stdout NoBuffering -- DO NOT REMOVE
-- Auto-generated code below aims at helping you parse
-- the standard input according to the problem statement.
input_line <- getLine
let n = read input_line :: Int
let value = [] :: [Int]
replicateM n $ do
input_line <- getLine
let pi = read input_line :: Int
hPutStrLn stderr (show input_line)
hPutStrLn stderr (show valueTab)
return $ app valueTab [pi]
-- hPutStrLn stderr "Debug messages..."
-- Write answer to stdout
--putStrLn input_line
return ()
So when I run this with
8
6
4
3 all on their own lines,
It prints 6, [], 4, [], 3 [].
Is this a problem with my printing, with my list declaration, with the way that I store them or? I have both value and valueTab to check whether it was a scope problem.
Note: The code is boilerplate code on a coding website that tests it on it's platform. Assume replicateM is just a loop that runs through the code x number of times.
It looks like you're doing a problem on codinggame.com. Other coding sites seem to do a better job with their Haskell templates, particularly for beginner exercises -- the template usually takes care of all the input and output, and you just need to supply the missing pure function. In contrast, codinggame.com's Haskell templates seem to assume the beginner has a pretty firm grasp of the IO monad, and leave out a lot of essential details (e.g., the fact that the result of the replicateM action should actually be bound to a variable) which you're expected to fill in.
The replicateM call in the original template probably looked something like:
replicateM n $ do
input_line <- getLine
let pi = read input_line :: Int -- maybe this line was there, maybe not
return ()
This expression creates a composite IO action that, when executed, will repeat the following subaction n times:
read a line, binding the string read to input_line
prepare to convert that line to an integer value pi (though this is never done because pi isn't used)
regardless of the string read, return "unit" (the value ()) as the result of the subaction
The value of the composite action is then a list of the values returned by the subactions. Since those were all units, the final value of the composite action is a list [(),(),()...()], with one () for each line read. However, because the value of this composite action is never bound to a variable (i.e., because there's no result <- ... before the replicateM expression), this list is thrown away.
So, this template provides a needlessly verbose method of reading n lines of input and doing nothing with them.
Fortunately, all you need to do to make this template do something useful is to have the subaction return a value that's useful (e.g., the integer pi) which will cause the composite action to return a list of the integers read, and then make sure you bind the resulting list to a variable using the <- notation.
In other words, you want to write:
main = do
...
pis <- replicateM n $ do
input_line <- getLine
let pi = read input_line :: Int
return pi
hPutStrLn stderr (show pis)
You won't need the helper function app, and you won't need to pre-declare a list valueTab to contain the result. The result is automatically produced by replicateM, and you just need to name it so you can use it.
The complete working program will look like:
import System.IO
import Control.Monad
type Int2 = [Int]
main :: IO ()
main = do
hSetBuffering stdout NoBuffering -- DO NOT REMOVE
-- Auto-generated code below aims at helping you parse
-- the standard input according to the problem statement.
input_line <- getLine
let n = read input_line :: Int
let value = [] :: [Int]
pis <- replicateM n $ do
input_line <- getLine
let pi = read input_line :: Int
return pi
hPutStrLn stderr (show pis)
-- hPutStrLn stderr "Debug messages..."
-- Write answer to stdout
return ()
Related
I found this code online, but it's not running.
main = do
xs <- getLine []
print xs
So how do I ask the user for list input in Haskell? I am new to Haskell, please explain when you answer. Thanks.
You do it e.g. like this:
main :: IO ()
main = do
xs <- getLine
let { ints :: [Int]
; ints = read xs
}
print $ take 2 ints
and you must type in the input in a valid list syntax, e.g.
[1,2,3]
Do take note, each line in a do-block must start at the same indentation level (unless explicit separators { ; } are used).
getLine is an IO action that produces a string, nothing else. You need to process that string once you receive it. As an example, here's an IO action that will parse an appropriate input into a list of Int values.
getIntList :: IO [Int]
getIntList = fmap read getLine
main = do
ints <- getIntList
print ints
There is a Read instance for lists, so the following works:
> read "[1,2,3]" :: [Int]
[1,2,3]
getIntList uses the Functor instance for IO to apply read to the string that getLine will produce; read's concrete type will be inferred from the type given to getIntList: since getIntList :: IO [Int], then fmap read :: IO String -> IO [Int], and so read :: String -> [Int] will be used.
I'm trying to test a small function (or rather, IO Action) that takes a command line argument and outputs it to the screen. My original (untestable) function is:
-- In Library.hs
module Library where
import System.Environment (getArgs)
run :: IO ()
run = do
args <- getArgs
putStrLn $ head args
After looking at this answer about mocking, I have come up with a way to mock getArgs and putStrLn by using a type class constrained type. So the above function becomes:
-- In Library.hs
module Library where
class Monad m => SystemMonad m where
getArgs :: m [String]
putStrLn :: String -> m ()
instance SystemMonad IO where
getArgs = System.Environment.getArgs
putStrLn = Prelude.putStrLn
run :: SystemMonad m => m ()
run = do
args <- Library.getArgs
Library.putStrLn $ head args
This Library., Prelude. and System.Environment. are to avoid compiler complaints of Ambigious Occurence. My test file looks like the following.
-- In LibrarySpec.hs
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
import Library
import Test.Hspec
import Control.Monad.State
data MockArgsAndResult = MockArgsAndResult [String] String
deriving(Eq, Show)
instance SystemMonad (State MockArgsAndResult) where
getArgs = do
MockArgsAndResult args _ <- get
return args
putStrLn string = do
MockArgsAndResult args _ <- get
put $ MockArgsAndResult args string
return ()
main :: IO ()
main = hspec $ do
describe "run" $ do
it "passes the first command line argument to putStrLn" $ do
(execState run (MockArgsAndResult ["first", "second"] "")) `shouldBe` (MockArgsAndResult ["first", "second"] "first")
I'm using a State monad that effectively contains 2 fields.
A list for the command line arguments where the mock getArgs reads from
A string that the mock putStrLn puts what was passed to it.
The above code works and seems to test what I want it to test. However, I'm wondering if there is some better / cleaner / more idiomatic way of testing this. For one thing, I'm using the same state to both put stuff into the test (my fake command line arguments), and then get stuff out of it (what was passed to putStrLn.
Is there a better way of doing what I'm doing? I'm more familiar with mocking in a Javascript environment, and my knowledge of Haskell is pretty basic (I arrived at the above solution by a fair bit of trial and error, rather than actual understanding)
The better way is to avoid needing to provide mock versions of getArgs and putStrLn by separating out the heart of the computation into a pure function.
Consider this example:
main = do
args <- getArgs
let n = length $ filter (\w -> length w < 5) args
putStrLn $ "Number of small words: " ++ show n
One could say that the heart of the computation is counting the number of small words which is a pure function of type [String] -> Int. This suggest that we should refactor the program like this:
main = do
args <- getArgs
let n = countSmallWords args
putStrLn $ "Number of small words: " ++ show n
countSmallWords :: [String] -> Int
countSmallWords ws = ...
Now we just test countSmallWords, and this is easy because it is pure function.
Suppose I am writing an OCaml program and my input will be a large stream of integers separated by spaces i.e.
let string = input_line stdin;;
will return a string which looks like e.g. "2 4 34 765 5 ..." Now, the program itself will take a further two values i and j which specify a small subsequence of this input on which the main procedure will take place (let's say that the main procedure is the find the maximum of this sublist). In other words, the whole stream will be inputted into the program but the program will only end up acting on a small subset of the input.
My question is: what is the best way to translate the relevant part of the input stream into something usable i.e. a string of ints? One option would be to convert the whole input string into a list of ints using
let list = List.map int_of_string(Str.split (Str.regexp_string " ") string;;
and then once the bounds i and j have been entered one easily locates the relevant sublist and its maximum. The problem is that the initial pre-processing of the large stream is immensely time-consuming.
Is there an efficient way of locating the small sublist directly from the large stream i.e. processing the input along with the main procedure?
OCaml's standard library is rather small. It provides necessary and sufficient set of orthogonal features, as should do any good standard library. But, usually, this is not enough for a casual user. That's why there exist libraries, that do the stuff, that is rather common.
I would like to mention two the most prominent libraries: Jane Street's Core library and Batteries included (aka Core and Batteries).
Both libraries provides a bunch of high-level I/O functions, but there exists a little problem. It is not possible or even reasonable to try to address any use case in a library. Otherwise the library's interface wont be terse and comprehensible. And your case is non-standard. There is a convention, a tacit agreement between data engineers, to represent a set of things with a set of lines in a file. And to represent one "thing" (or a feature) with a line. So, if you have a dataset where each element is a scalar, you should represent it as a sequence of scalars separated by a newline. Several elements on a single line is only for multidimensional features.
So, with a proper representation, your problem can be solve as simple as (with Core):
open Core.Std
let () =
let filename = "data" in
let max_number =
let open In_channel in
with_file filename
~f:(fold_lines ~init:0
~f:(fun m s -> Int.(max m ## of_string s))) in
printf "Max number is %s is %d\n" filename max_number
You can compile and run this program with corebuild test.byte -- assuming that code is in a file name test.byte and core library is installed (with opam install core if you're using opam).
Also, there exists an excellent library Lwt, that provides a monadic high-level interface to the I/O. With this library, you can parse a set of scalars in a following way:
open Lwt
let program =
let filename = "data" in
let lines = Lwt_io.lines_of_file filename in
Lwt_stream.fold (fun s m -> max m ## int_of_string s) lines 0 >>=
Lwt_io.printf "Max number is %s is %d\n" filename
let () = Lwt_main.run program
This program can be compiled and run with ocamlbuild -package lwt.unix test.byte --, if lwt library is installed on your system (opam install lwt).
So, that is not to say, that your problem cannot be solved (or is hard to be solved) in OCaml, it is just to mention, that you should start with a proper representation. But, suppose, you do not own the representation, and cannot change it. Let's look, how this can be solved efficiently with OCaml. As previous examples represent, in general your problem can be described as a channel folding, i.e. an consequential application of a function f to each value in a file. So, we can define a function fold_channel, that will read an integer value from a channel and apply a function to it and the previously read value. Of course, this function can be further abstracted, by lifting the format argument, but for the demonstration purpose, I suppose, this will be enough.
let rec fold_channel f init ic =
try Scanf.fscanf ic "%u " (fun s -> fold_channel f (f s init) ic)
with End_of_file -> init
let () =
let max_value = open_in "atad" |> fold_channel max 0 in
Printf.printf "max value is %u\n" max_value
Although, I should note that this implementation is not for a heavy duty work. It is even not tail-recursive. If you need really efficient lexer, you can use ocaml's lexer generator, for example.
Update 1
Since there is a word "efficient" in the title, and everybody likes benchmarks, I've decided to compare this three implementations. Of course, since pure OCaml implementation is not tail-recursive it is not comparable to others. You may wonder, why it is not tail-recursive, as all calls to fold_channel is in a tail position. The problem is with exception handler - on each call to the fold channel, we need to remember the init value, since we're going to return it. This is a common issue with recursion and exceptions, you may google it for more examples and explanations.
So, at first we need to fix the third implementation. We will use a common trick with option value.
let id x = x
let read_int ic =
try Some (Scanf.fscanf ic "%u " id) with End_of_file -> None
let rec fold_channel f init ic =
match read_int ic with
| Some s -> fold_channel f (f s init) ic
| None -> init
let () =
let max_value = open_in "atad" |> fold_channel max 0 in
Printf.printf "max value is %u\n" max_value
So, with a new tail-recursive implementation, let's try them all on a big-data. 100_000_000 numbers is a big data for my 7 years old laptop. I've also added a C implementations as a baseline, and an OCaml clone of the C implementation:
let () =
let m = ref 0 in
try
let ic = open_in "atad" in
while true do
let n = Scanf.fscanf ic "%d " (fun x -> x) in
m := max n !m;
done
with End_of_file ->
Printf.printf "max value is %u\n" !m;
close_in ic
Update 2
Yet another implementation, that uses ocamllex. It consists of two files, a lexer specification lex_int.mll
{}
let digit = ['0'-'9']
let space = [' ' '\t' '\n']*
rule next = parse
| eof {None}
| space {next lexbuf}
| digit+ as n {Some (int_of_string n)}
{}
And the implementation:
let rec fold_channel f init buf =
match Lex_int.next buf with
| Some s -> fold_channel f (f s init) buf
| None -> init
let () =
let max_value = open_in "atad" |>
Lexing.from_channel |>
fold_channel max 0 in
Printf.printf "max value is %u\n" max_value
And here are the results:
implementation time ratio rate (MB/s)
plain C 22 s 1.0 12.5
ocamllex 33 s 1.5 8.4
Core 62 s 2.8 4.5
C-like OCaml 83 s 3.7 3.3
fold_channel 84 s 3.8 3.3
Lwt 143 s 6.5 1.9
P.S. You can see, that in this particular case Lwt is an outlier. This doesn't mean that Lwt is slow, it is just not its granularity. And I would like to assure you, that to my experience Lwt is a well suited tool for a HPC. For example, in one of my programs it processes a 30 MB/s network stream in a real-time.
Update 3
By the way, I've tried to address the problem in an abstract way, and I didn't provide a solution for your particular example (with j and k). Since, folding is a generalization of the iteration, it can be easily solved by extending the state (parameter init) to hold a counter and check whether it is contained in a range, that was specified by a user. But, this leads to an interesting consequence: what to do, when you have outran the range? Of course, you can continue to the end, just ignoring the output. Or you can non-locally exit from a function with an exception, something like raise (Done m). Core library provides such facility with a with_return function, that allows you to break out of your computation at any point.
open Core.Std
let () =
let filename = "data" in
let b1,b2 = Int.(of_string Sys.argv.(1), of_string Sys.argv.(2)) in
let range = Interval.Int.create b1 b2 in
let _,max_number =
let open In_channel in
with_return begin fun call ->
with_file filename
~f:(fold_lines ~init:(0,0)
~f:(fun (i,m) s ->
match Interval.Int.compare_value range i with
| `Below -> i+1,m
| `Within -> i+1, Int.(max m ## of_string s)
| `Above -> call.return (i,m)
| `Interval_is_empty -> failwith "empty interval"))
end in
printf "Max number is %s is %d\n" filename max_number
You may use the Scanf module family of functions. For instance, Scanf.fscanf let you read tokens from a channel according to a string format (which is a special type in OCaml).
Your program can be decomposed in two functions:
one which skip a number i of tokens from the input channel,
one which extract the maximum integer out of a number j from a channel
Let's write these:
let rec skip_tokens c i =
match i with
| i when i > 0 -> Scanf.fscanf c "%s " (fun _ -> skip_tokens c ## pred i)
| _ -> ()
let rec get_max c j m =
match j with
| j when j > 0 -> Scanf.fscanf c "%d " (fun x -> max m x |> get_max c (pred j))
| _ -> m
Note the space after the token format indicator in the string which tells the scanner to also swallow all the spaces and carriage returns in between tokens.
All you need to do now is to combine them. Here's a small program you can run from the CLI which takes the i and j parameters, expects a stream of tokens, and print out the maximum value as wanted:
let _ =
let i = int_of_string Sys.argv.(1)
and j = int_of_string Sys.argv.(2) in
skip_tokens stdin (pred i);
get_max stdin j min_int |> print_int;
print_newline ()
You could probably write more flexible combinators by extracting the recursive part out. I'll leave this as an exercise for the reader.
I don't know why this code does not run. I just simply wanted to fill 0's with a number like 4 and return the results. I am new in Haskell sorry if my question is very basic.
fill [] = []
fill (x:xs) = if x==0 then 0 else 4 : fill xs
main = do
fill [0,1,0]
Let's see what the compiler is actually looking at when it sees your function fill:
(I don't have ghc at my disposal right now, but it should look something like below)
> :t fill
fill :: (Num a) => [a] -> [a] -- or fill:: [Integer] -> [Integer] for simplicity
Okay, that's a function that takes a list of numerics to return another list of numerics. Let's look at main:
> :t main
main :: IO ()
Wait, what's IO doing there? Well, main the entry point for all standalone haskell programs. It exposes your functions out into the real world modelled by the poorly named IO wrapper.
Now, what did you actually want to accomplish here?
I just simply wanted to fill 0's with a number like 4 and return the
results.
Right, so let's get down to it. Here's my type definition - all I'm saying is that, whatever be the type of lists that I get here, characterised by a - it should conform to numbers, that's what I mean why I constrain the types to Num. Num here is a typeclass, which you can look more about here.
fill :: (Num a) => [a] -> [a]
Now, when I see an empty list, I return back an empty list. Easy -
fill [] = []
In your function definition, you're not replacing zeroes at all - let's fix that:
fill (x:xs) = if x == 0
then 4:fill xs
else x:fill xs
Okay, we're still not done here - how do we expose fill to our outside world? Cometh the main, cometh the world. Cheesy, I know :-) But main wraps everything into an IO, how do we wrap our little function into it? Ah, how do I display strings out into IO? putStrLn or print?
main :: IO ()
main = putStrLn "Hello World!"
We're now safely esconsced in our little echo chambers muttering "hello world" to ourselves.
Let's make it a bit more useful. Now, I'm just going to print out our list:
> :t print
print :: Show a => a -> IO ()
Like Num, Show is also another typeclass. I leave you to figure this out as homework. :-)
main = print $ fill [0,1,0,1]
which prints:
[4,1,4,1]
Just wrap if-then-else in parentheses:
fill [] = []
fill (x:xs) = (if x==0 then 0 else 4) : fill xs
This should work:
fill [] = []
fill (x:xs) = if x==0
then 4:fill xs
else x:fill xs
main = do
putStrLn $ show (fill [0,1,0])
When you check for 0, you should just not return 0 but along with 0 you should call the function fill recursively.
And in main function, show is used for taking a type and returning the String equivalent for it so that it can be printed in the do block.
getChar :: Int -> IO Char
getChar n = do
c <- getLine
return (c !! n)
The program must needs a number and a line and it will return char, but how do I catch exception, if the number is too big?
I tried like this but it doesnt seem to work
getChar n
= do
c <-getLine
| n>=0 && n < b
= return c !! n
| otherwise
= error "Too big number"
where
b = length c
This is not a homework, im trying to involve myself. Google didint give me useful answers
Couldn't implement catch in there. Examples?
You probably want to restructure things a bit as you've got IO mixed up in something it doesn't have to be. What about changing the signature to something like this?
getChar :: Int -> String -> Maybe Char
getChar n x | n < length x = Just (x !! n)
| otherwise = Nothing
Data.Maybe allows you to indicate that you are either going to return something (e.g. the length is within range) or Nothing (the length isn't within range). The function that calls getChar can then decide what to do with things. Data.Either provides a way of returning an error message with an error instead. From what I've seen (and I'm by no means an expert) exceptions are rarely used in Haskell, and choice types such as Either or Maybe are much more commonly used.
Now in the code that calls this, you can use pattern matching to see what happened e.g.
main :: IO ()
main = do
x <- getLine
let z = getChar' 5 x
case z of
(Just z) -> print $ "The 5th character is " ++ show z
Nothing -> print $ "The 5th character is out of range"
You can use the drop function to drop the first n characters of the line (drop will just give an empty result if there are fewer than n chars), and the listToMaybe function to turn a list to a Maybe (either Just c where c is the first element of the list, or Nothing if the list is empty):
import Data.Maybe (listToMaybe)
getchar :: Int -> IO (Maybe Char)
getchar n = do
line <- getLine
return . listToMaybe . drop n $ line
getChar' :: Int -> IO Char
getChar' n =
do
c <- getLine
if (n < length c)
then
return (c !! n)
else
getChar' n
You can do something like above. This is just an example though. But, since you are a beginner, it is strongly recommended not to play with IO and Monads. You can come to it after you get familiarized with pure functional concepts.