I've been learning Haskell in the last 2 weeks and decided to try challenges at places such as HackerRank. This has required learning IO. I have read many answers on StackExchange and the general gist is you don't unwrap IO a, you just manipulate that data inside the IO function. That being the case what is the point of all the pure functions, if I'm not allowed to send data from main out to them? Here is some code that reads how many test cases, then for each test case reads N ordered pairs.
main = do
test <- getLine
replicateM (read test) doTest
doTest = do
query<-getLine
rs<-replicateM (read query) readPair
return rs -- just here to make the file compile
readPair :: IO (Int, Int)
readPair = do
input <- getLine
let a = words input in return (read (a!!0) :: Int, read (a!!1) ::Int)
At this point I have a IO [(Int, Int)] inside of rs. I would like to send that data to this function:
validFunction :: [(Int,Int)]->Bool
validFuntion [] = True
validFunction (x:[]) = True
validFunction (x:xs) = (not $ elem (snd x) (fmap snd xs)) && validFunction xs
But I can't seem to figure out how to do that. Any help or suggestions about how to call this function with the data I've read from the user would be appreciated. Or if I'm going about it from the wrong angle, and pointers on what I should be doing would also work.
Edit: From reading lots of other questions on here I now have the general idea that once you're in IO you're stuck there. But what I can't seem to find is the syntax to call a pure function with IO data and get back IO data. I've tried some of the following :
fmap validFunction [rs] :: IO Bool -- tried it with just rs without [] as well
mapM validFunction [rs] :: IO Bool
validFunction rs :: IO Bool
I was able to get this to work:
putStrLn . f . validFunction $ rs
though I'm still not clear on why this lets you pass the IO [(Int, Int)] to validFunction.
First of all, if you use x <- act in do, you essentially have a value. Unless you did something very suspicious, x isn't a IO something, but a something: So it's perfectly fine to use
foo :: Int -> Char
foo = …
bar :: IO Int
bar = …
fooDo :: IO Char
fooDo = do
number <- bar
return (foo number) -- apply foo directly on number
However, IO is an instance of Functor, so we can use fmap to lift foo:
liftedFoo :: IO Int -> IO Char
liftedFoo = fmap foo
So we could have written fooDo like this:
fooDo = fmap foo readLn
Although it's name is now misleading, it still does the same as before. But let's leave this naming voodoo aside, how would you tackle this? Well, your doTest has the correct type:
doTest :: IO [(Int, Int)]
doTest = do
query <- getLine
rs <- replicateM (read query) readPair
return rs
So all that's missing is calling validFunction. We can do that like in fooDo:
doTest :: IO Bool
doTest = do
query <- getLine
rs <- replicateM (read query) readPair
return (validFunction rs)
-- ^^^^^^^^^^^^^^^^^^
-- no IO inside here
-- ^^^^^^
-- back
-- to IO
Or we can fmap over another IO value, like replicateM (read query) readPair:
doTest :: IO Bool
doTest = do
query <- getLine
fmap validFunction (replicateM (read query) readPair)
The latter is harder to read, though. But you write your fooDo doTest as you want to do.
Related
I am using a library that I can provide with a function a -> IO (), which it will call occasionally.
Because the output of my function depends not only on the a it receives as input, but also on the previous a's, it would be much easier for me to write a function [a] -> IO (), where [a] is infinite.
Can I write a function:
magical :: ([a] -> IO ()) -> (a -> IO ())
That collects the a's it receives from the callback and passes them to my function as a lazy infinite list?
The IORef solution is indeed the simplest one. If you'd like to explore a pure (but more complex) variant, have a look at conduit. There are other implementations of the same concept, see Iteratee I/O, but I found myself conduit to be very easy to use.
A conduit (AKA pipe) is an abstraction of of program that can accept input and/or produce output. As such, it can keep internal state, if needed. In your case, magical would be a sink, that is, a conduit that accepts input of some type, but produces no output. By wiring it into a source, a program that produces output, you complete the pipeline and then ever time the sink asks for an input, the source is run until it produces its output.
In your case you'd have roughly something like
magical :: Sink a IO () -- consumes a stream of `a`s, no result
magical = go (some initial state)
where
go state = do
m'input <- await
case m'input of
Nothing -> return () -- finish
Just input -> do
-- do something with the input
go (some updated state)
This is not exactly what you asked for, but it might be enough for your purposes, I think.
magical :: ([a] -> IO ()) -> IO (a -> IO ())
magical f = do
list <- newIORef []
let g x = do
modifyIORef list (x:)
xs <- readIORef list
f xs -- or (reverse xs), if you need FIFO ordering
return g
So if you have a function fooHistory :: [a] -> IO (), you can use
main = do
...
foo <- magical fooHistory
setHandler foo -- here we have foo :: a -> IO ()
...
As #danidaz wrote above, you probably do not need magical, but can play the same trick directly in your fooHistory, modifying a list reference (IORef [a]).
main = do
...
list <- newIORef []
let fooHistory x = do
modifyIORef list (x:)
xs <- readIORef list
use xs -- or (reverse xs), if you need FIFO ordering
setHandler fooHistory -- here we have fooHistory :: a -> IO ()
...
Control.Concurrent.Chan does almost exactly what I wanted!
import Control.Monad (forever)
import Control.Concurrent (forkIO)
import Control.Concurrent.Chan
setHandler :: (Char -> IO ()) -> IO ()
setHandler f = void . forkIO . forever $ getChar >>= f
process :: String -> IO ()
process ('h':'i':xs) = putStrLn "hi" >> process xs
process ('a':xs) = putStrLn "a" >> process xs
process (x:xs) = process xs
process _ = error "Guaranteed to be infinite"
main :: IO ()
main = do
c <- newChan
setHandler $ writeChan c
list <- getChanContents c
process list
This seems like a flaw in the library design to me. You might consider an upstream patch so that you could provide something more versatile as input.
I'm writing a program that should be able to simulate many instances of trying the martingale betting system with roulette. I would like main to take an argument giving the number of tests to perform, perform the test that many times, and then print the number of wins divided by the total number of tests. My problem is that instead of ending up with a list of Bool that I could filter over to count successes, I have a list of IO Bool and I don't understand how I can filter over that.
Here's the source code:
-- file: Martingale.hs
-- a program to simulate the martingale doubling system
import System.Random (randomR, newStdGen, StdGen)
import System.Environment (getArgs)
red = [1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36]
martingale :: IO StdGen -> IO Bool
martingale ioGen = do
gen <- ioGen
return $ martingale' 1 0 gen
martingale' :: Real a => a -> a -> StdGen -> Bool
martingale' bet acc gen
| acc >= 5 = True
| acc <= -100 = False
| otherwise = do
let (randNumber, newGen) = randomR (0,37) gen :: (Int, StdGen)
if randNumber `elem` red
then martingale' 1 (acc + bet) newGen
else martingale' (bet * 2) (acc - bet) newGen
main :: IO ()
main = do
args <- getArgs
let iters = read $ head args
gens = replicate iters newStdGen
results = map martingale gens
--results = map (<-) results
print "THIS IS A STUB"
Like I have in my comments, I basically want to map (<-) over my list of IO Bool, but as I understand it, (<-) isn't actually a function but a keyword. Any help would be greatly appreciated.
map martingale gens will give you something of type [IO Bool]. You can then use sequence to unpack it:
sequence :: Monad m => [m a] -> m [a]
A more natural alternative is to use mapM directly:
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
i.e. you can write
results <- mapM martingale gens
Note - even after doing it this way, your code feels a bit unnatural. I can see some advantages to the structure, in particular because martingale' is a pure function. However having something of type IO StdGen -> IO Bool seems a bit odd.
I can see a couple of ways to improve it:
make martingale' return an IO type itself and push the newStdGen call all the way down into it
make gens use replicateM rather than replicate
You may want to head over to http://codereview.stackexchange.com for more comprehensive feedback.
I have a file number.txt which contains a large number and I read it into an IO String like this:
readNumber = readFile "number.txt" >>= return
In another function I want to create a list of Ints, one Int for each digit…
Lets assume the content of number.txt is:
1234567890
Then I want my function to return [1,2,3,4,5,6,7,8,9,0].
I tried severall versions with map, mapM(_), liftM, and, and, and, but I got several error messages everytime, which I was able to reduce to
Couldn't match expected type `[m0 Char]'
with actual type `IO String'
The last version I have on disk is the following:
module Main where
import Control.Monad
import Data.Char (digitToInt)
main = intify >>= putStrLn . show
readNumber = readFile "number.txt" >>= return
intify = mapM (liftM digitToInt) readNumber
So, as far as I understand the error, I need some function that takes IO [a] and returns [IO a], but I was not able to find such thing with hoogle… Only the other way round seemes to exist
In addition to the other great answers here, it's nice to talk about how to read [IO Char] versus IO [Char]. In particular, you'd call [IO Char] "an (immediate) list of (deferred) IO actions which produce Chars" and IO [Char] "a (deferred) IO action producing a list of Chars".
The important part is the location of "deferred" above---the major difference between a type IO a and a type a is that the former is best thought of as a set of instructions to be executed at runtime which eventually produce an a... while the latter is just that very a.
This phase distinction is key to understanding how IO values work. It's also worth noting that it can be very fluid within a program---functions like fmap or (>>=) allow us to peek behind the phase distinction. As an example, consider the following function
foo :: IO Int -- <-- our final result is an `IO` action
foo = fmap f getChar where -- <-- up here getChar is an `IO Char`, not a real one
f :: Char -> Int
f = Data.Char.ord -- <-- inside here we have a "real" `Char`
Here we build a deferred action (foo) by modifying a deferred action (getChar) by using a function which views a world that only comes into existence after our deferred IO action has run.
So let's tie this knot and get back to the question at hand. Why can't you turn an IO [Char] into an [IO Char] (in any meaningful way)? Well, if you're looking at a piece of code which has access to IO [Char] then the first thing you're going to want to do is sneak inside of that IO action
floob = do chars <- (getChars :: IO [Char])
...
where in the part left as ... we have access to chars :: [Char] because we've "stepped into" the IO action getChars. This means that by this point we've must have already run whatever runtime actions are required to generate that list of characters. We've let the cat out of the monad and we can't get it back in (in any meaningful way) since we can't go back and "unread" each individual character.
(Note: I keep saying "in any meaningful way" because we absolutely can put cats back into monads using return, but this won't let us go back in time and have never let them out in the first place. That ship has sailed.)
So how do we get a type [IO Char]? Well, we have to know (without running any IO) what kind of IO operations we'd like to do. For instance, we could write the following
replicate 10 getChar :: [IO Char]
and immediately do something like
take 5 (replicate 10 getChar)
without ever running an IO action---our list structure is immediately available and not deferred until the runtime has a chance to get to it. But note that we must know exactly the structure of the IO actions we'd like to perform in order to create a type [IO Char]. That said, we could use yet another level of IO to peek at the real world in order to determine the parameters of our action
do len <- (figureOutLengthOfReadWithoutActuallyReading :: IO Int)
return $ replicate len getChar
and this fragment has type IO [IO Char]. To run it we have to step through IO twice, we have to let the runtime perform two IO actions, first to determine the length and then second to actually act on our list of IO Char actions.
sequence :: [IO a] -> IO [a]
The above function, sequence, is a common way to execute some structure containing a, well, sequence of IO actions. We can use that to do our two-phase read
twoPhase :: IO [Char]
twoPhase = do len <- (figureOutLengthOfReadWithoutActuallyReading :: IO Int)
putStrLn ("About to read " ++ show len ++ " characters")
sequence (replicate len getChar)
>>> twoPhase
Determining length of read
About to read 22 characters
let me write 22 charac"let me write 22 charac"
You got some things mixed up:
readNumber = readFile "number.txt" >>= return
the return is unecessary, just leave it out.
Here is a working version:
module Main where
import Data.Char (digitToInt)
main :: IO ()
main = intify >>= print
readNumber :: IO String
readNumber = readFile "number.txt"
intify :: IO [Int]
intify = fmap (map digitToInt) readNumber
Such a function can't exists, because you would be able to evaluate the length of the list without ever invoking any IO.
What is possible is this:
imbue' :: IO [a] -> IO [IO a]
imbue' = fmap $ map return
Which of course generalises to
imbue :: (Functor f, Monad m) => m (f a) -> m (f (m a))
imbue = liftM $ fmap return
You can then do, say,
quun :: IO [Char]
bar :: [IO Char] -> IO Y
main = do
actsList <- imbue quun
y <- bar actsLists
...
Only, the whole thing about using [IO Char] is pointless: it's completely equivalent to the much more straightforward way of working only with lists of "pure values", only using the IO monad "outside"; how to do that is shown in Markus's answer.
Do you really need many different helper functions? Because you may write just
main = do
file <- readFile "number.txt"
let digits = map digitToInt file
print digits
or, if you really need to separate them, try to minimize the amount of IO signatures:
readNumber = readFile "number.txt" --Will be IO String
intify = map digitToInt --Will be String -> [Int], not IO
main = readNumber >>= print . intify
I want to write a function that read some data using getLine and return i.e. a tuple (Integer, Integer) but using do-notation. Something like this (of course it doesn't work):
fun :: (Integer, Integer)
fun = do
a <- read (getLine::Integer)
b <- read (getLine::Integer)
return (a, b)
Do I have to write my own monad for this? Is there any solution to not writing a new monad?
EDIT
So I can write main function that use fun, I think it's the only solution:
main :: IO ()
main = do
tuple <- fun
putStrLn (show tuple)
fun :: IO (Integer, Integer)
fun = do
a1 <- getLine
b1 <- getLine
let a = read (a1)
b = read (b1)
return (a, b)
And above code works.
You type of function should be
fun :: IO (Integer, Integer)
as mentioned by #kaan you should not try to get a mondic value (with side effects) out of the monad as that will break referential transparency. Running fun should always return same value no matter how many times it is run and if we use your type this will not happen. However if the type is IO (Integer, Integer) then it returns the same action every time you use that function and running this action actually perform the side effect of reading the values from the console.
Coming back to using you function. You can do that inside another IO monad like
main = do
(a,b) <- fun
print a
print b
Although there are ways of getting things out of IO using unsafe functions but that is not recommended until you know exactly what you are doing.
As mentioned, you will need to give fun the type IO (Integer, Integer) instead of (Integer, Integer). However, once you have resigned yourself to this fate, there are many ways to skin this cat. Here are a handful of ways to get your imagination going.
fun = do
a <- getLine
b <- getLine
return (read a, read b)
-- import Control.Applicative for (<$>)
-- can also spell (<$>) as fmap, liftA, liftM, and others
fun = do
a <- read <$> getLine
b <- read <$> getLine
return (a, b)
fun = do
a <- readLn
b <- readLn
return (a, b)
fun = liftM2 (,) readLn readLn
-- different type!
-- use in main like this:
-- main = do
-- [a, b] <- fun
-- foo
-- import Control.Monad for replicateM
fun :: IO [Integer]
fun = replicateM 2 readLn
I started to play around with haskell and I want to write a parser for binary data that I already did with all programming languages I tried so far.
But I am struggling with the monad concept and a general handling of data in haskell.
So far I have the following:
data TestData = T { value :: String } deriving (Show)
data TestData2 = T2 { value2 :: String } deriving (Show)
testFunc :: Handle -> IO BS.ByteString
testFunc hs = BS.hGet hs 4
main = do
handle <- SIO.openFile "c:/temp/test.bin" SIO.ReadMode
contents1 <- BS.hGet handle 4
contents2 <- testFunc handle
contents3 <- BS.hGet handle 4
putStrLn (show (T (bytesToString contents1)))
putStrLn (show (T (bytesToString contents2)))
putStrLn (show (T (bytesToString contents3)))
The data I want to read are multiple nested structs(spoken i C).
So what I want to know is how to write my testFunc that it will return a data type of my own TestData2 type. But still can be used in the do chain of functions.
Anyone can give me a hint?
You can do it this way using do notation:
testFunc :: Handle -> IO TestData2
testFunc hs = do contents <- BS.hGet hs 4
return $ T2 (bytesToString contents)
Or you can do it this way using <$> from Control.Applicative:
testFunc :: Handle -> IO TestData2
testFunc hs = T2 . bytesToString <$> BS.hGet hs 4