I have some code that looks like this
listOfIOByteStrings = simpleHttp <$> apiLinks :: [IO ByteString]
where apiLinks is a list of links which calls some API function.
I also have this function
z = sequence listOfIOByteStrings
sequence has this type sequence :: Monad m => t (m a) -> m (t a)
What I want to do is add a thread delay between each ByteString's evaluation.
I'm thinking of using threadDelay threadDelay :: Int -> IO ()
This is what I'm doing ultimately
listOfContent <- z
pPrint $ filteredTitles . onlyElems . parseXML <$> listOfContent
where
parseXML :: ByteString -> [Content]
onlyElems :: [Content] -> [Element]
and
filteredTitles :: [Element] -> [String]
Applying thread-delay between result of sequence would be something like this
printing (filteredTitles . onlyElems . parseXML (bytestring of link1))...
delay of 1 sec...
printing (filteredTitles . onlyElems . parseXML (bytestring of link2))...
delay of 1 sec...
printing (filteredTitles . onlyElems . parseXML (bytestring of link3))...
delay of 1 sec...
I'm not sure how I should go about doing that.
One of way to do that is using forM_ as
...
do listOfContent <- z
forM_ listOfContent $
\content -> do pPrint $ (filteredTitles . onlyElems . parseXML) content
threadDelay 1000000
I don't quite follow all the types in your pipeline, so consider this a rough sketch that can be fleshed out. First, you don't want to call sequence too early. Keep your list of IO Bytestring values for now.
Next, you want some function (defined in terms of filteredTitles . onlyElems . parseXML) that takes a single Bytestring and returns an IO (). If pPrint is the write type, this might simply be
process :: IO ByteString -> IO ()
process ibs = do
bs <- ibs
pPrint (filteredTitles . onlyElems . parseXML $ bs)
map process (apiLinks >>= simpleHttp) should result in a list of type [IO ()]. That could probably be rewrittn in a less clunky fashion, but now we can get to the heart of the answer, which is using intersperse to insert your thread delays before finally sequencing the [IO ()] to get IO [()].
import Data.List
let results = map process (apiLinks >>= simpleHttp)
actions = intersperse (threadDelay 1) results
in sequence actions
intersperse :: a -> [a] -> [a] works by inserting its first argument between each element of its second. A simple example using strings:
> intersperse '-' "abc"
"a-b-c"
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'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.
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'm confusing with some stuff in haskell.First I'll explain my problem clearly,
I have function call "func1" that take result from the DB
type definition
func1 :: IO[[String]]
func1 = do
xx <- main --returns the sql output
return (map (map fromSql) xx :: [[String]])
I need to write two functions that gives me funcWnt :: IO[[String]] -> [[String]] and funcWnt2 :: [String] -> Splice m
I tried <- within "funcWnt" but that was not succeed.Could any one tell me how to do this?or any other way to do this?'funcWnt2 :: [String] -> I have created,I want to know 'funcWnt' function
thnxxxx!!
As a general observation: Try to always think about what your functions do with their inputs, assuming they've already got them. Your functions seem to be concerned with both getting their inputs and transforming them. Let them just transform, and use some outer function to get them their inputs.
Let's see if we can take how you're thinking of this, and re-formulate it along these new lines:
You have:
readDB :: IO [[SqlValue]]
readDB = ... -- not given here
func1 :: IO [[String]]
func1 = do
xx <- readDB
return (map (map fromSql) xx)
You now want to write something that transforms this. One way is to just replicate the pattern you've already used:
funcWnt :: IO [[String]]
yy <- func1
return ... -- some transformation of yy
funcWnt2 :: IO (Splice m)
zz <- funcWnt
return ... -- some transformation of zz into a Splice m
Notice that written in the style of func1 these are not functions at all, but values in IO. If these functions don't do IO, (and func1 certainly doesn't), then writing this way is non-idiomatic, awkward, non-modular, and puts all your pure code inside IO. Instead, consider writing them purely:
func1 :: [[SqlValue]] -> [[String]]
func1 = map (map fromSql)
funcWnt :: [[String]] -> [[String]]
funcWnt = ... -- some transformation
funcWnt2 :: [[String]] -> Splice m
funcWnt2 = ... -- some transformation into a Splice m
Now you can easily combine them, and use them in a single IO value:
dbToSplice :: IO (Splice m)
dbToSplice = do
xx <- readDB
return $ (funcWnt2 . funcWnt . func1) xx
Or perhaps, more idiomatically (don't be afraid of >>=, learn it early):
dbToSplice :: IO (Splice m)
dbToSplice = readDB >>= return . funcWnt2 . funcWnt . func1
Now, if, just for sake of argument, funcWnt2 needed to do something in IO. Then the definitions would look like:
funcWnt2 :: [[String]] -> IO (Splice m)
funcWnt2 zz = do
... -- compute something with zz
return ... -- returning some Splice m
dbToSplice :: IO (Splice m)
dbToSplice = readDB >>= funcWnt2 . funcWnt . func1
Lastly, notice that I put type signatures on every top level function. You should get in the habit of doing this too. Not only does it help clarify your intent (to yourself, other developers, or even yourself a week from now), but it eliminates many awkward type annotations like you had to put inside func1.