Simple counter in IO - haskell
I'm trying to create a simple counter which increases by 1 indefinitely, using IO.
I've been scratching my head ever since...
Ideally, I would like to do something along the lines of
tick = do putStr (counter)
counter + 1
where counter = 0
Then repeat the process. Then repeat the first 2 expressions. Or something along the lines of:
tick = tick'
where
counter = 1
tick' counter | counter > 0 = do putStrLn (show counter)
tick' (counter + 1)
| otherwise = tick
Which gives me errors :/
Any help is appreciated :)
There are a couple ways to do this without using a mutable cell. You already did it with your second attempt, there's just a little error. You need to pass an initial value to the tick' function, not "set it" (haskell does not have an idea of assigning variables -- only definitions. If the line x = y appears, x will be y for its entire lifetime).
tick = tick' 0
where ...
The counter = 0 line is not doing anything; it is defining a name that is never used. The counter used in the tick' function is bound as one of its arguments (and shadows the one defined to be 0). Take some time to stare at it with that in mind, see if that makes sense.
There is a nice "higher order" way we can do this too. Essentially we want to run the infinitely long block of code:
do
print 0
print 1
print 2
...
There is a function called sequence :: [IO a] -> IO [a] (see caveat below) that will take a list of actions and construct an action. So if we can construct the list [print 0, print 1, print 2, ...] then we can pass it to sequence to build the infinitely long block we are looking for.
Take note here, this is a very important concept in Haskell: [print 0, print 1, print 2] does not print those three numbers then construct the list [0,1,2]. Instead it is itself a list of actions, whose type is [IO ()]. Making the list does nothing; it is only when you bind an action to main that it will be executed. For example, we might say:
main = do
let xs = [putStrLn "hello", getLine >> putStrLn "world"]
xs !! 0
xs !! 0
xs !! 1
xs !! 1
xs !! 0
This would twice print hello, twice get a line and print world after each, then once print hello again.
With that concept, it is easy to build the list of actions [print 0, print 1, ...] with a list comprehension:
main = sequence [ print x | x <- [0..] ]
We can simplify a bit:
main = sequence (map (\x -> print x) [0..])
main = sequence (map print [0..])
So map print [0..] is the list of actions [print 0, print 1, ...] we were looking for, then we just pass that to sequence which chains them together.
This pattern of sequence is common, and has its own mapM:
mapM :: (a -> IO b) -> [a] -> IO [b]
mapM f xs = sequence (map f xs)
Thus:
main = mapM print [0..]
About as simple as you could want.
One note about performance: since we are not using the output of these functions, we should be using sequence_ and mapM_, with trailing underscores, which are optimized for that purpose. Usually this wouldn't matter in a Haskell program because of garbage collection, but in this particular use case is kind of a special case because of various subtleties. You'll find that without the _s, the memory usage of your program gradually grows as the list of results (in this case [(),(),(),...]) is constructed but never used.
Caveat: I have given the type signatures of sequence and mapM specialized to IO, not a general monad, so that the reader does not have to learn about the orthogonal concepts of actions having types and typeclasses at the same time.
Well, let's go back to basics. What you want appears to be an IO action that when bound, prints and increments a counter? I'm going to work from that assumption.
The first thing you need is some mutable cell, since you're using the same action each time. It needs to have something mutable inside it to do something different each time it's used. I'd go with an IORef for this case.
But keeping that IORef hidden is a bit tricky. Especially since globals are bad. The best way to do it is create the IO action from inside another IO action, and then close over the IORef. Doing so gives you something like this:
import Data.IORef
mkCounter :: IO (IO ())
mkCounter = do
ref <- newIORef 0
return $ do
counter <- readIORef ref
print counter
writeIORef ref $ counter + 1
This can be used by doing something like this:
main = do
tick <- mkCounter
tick
tick
tick
Your second implementation is really close!
tick = tick'
where
counter = 1
tick' counter | counter > 0 = do putStrLn (show counter)
tick' (counter + 1)
| otherwise = tick
Let's look at the errors for this:
Couldn't match expected type `IO b0' with actual type `a0 -> IO b0'
In the expression: tick'
Let's add some types to make sure we're getting what we want.
tick is an IO action. We don't care what value the action encapsulates, since the whole
point of it is to run forever.
tick :: IO a
Now our error is:
Couldn't match expected type `IO a' with actual type `a0 -> IO b0'
In the expression: tick'
Well, that's pretty much the same, no help there. Let's keep going.
tick' is a function that takes some integer and returns an IO action
that prints the integer and repeats tick' on the next value. Again, we don't care what
value the action encapsulates, since it runs forever.
tick' :: Int -> IO b
Wait, now that error makes sense! We defined tick = tick', but the two things have fundamentally different types. One is an action (tick) one is a function that returns an action (tick'). All we need to do is give tick' some value to get the action, so let's do that.
You'd tried to do that by saying where counter = 1 but all that did is define counter as 1 within the statement tick = tick', and since counter isn't mentioned there, it wasn't used.
When you said tick' counter | ... =, you weren't referring to the same counter as on the line above. There, you were defining another variable called counter that was only in scope within the definition of tick'.
So now our code looks like:
tick :: IO a
tick = tick' 1
where
tick' :: Int -> IO b
tick' counter | counter > 0 = do putStrLn (show counter)
tick' (counter + 1)
| otherwise = tick
If we try to compile it, ghc doesn't complain, and if we try it out in ghci it runs as desired:
% ghci
ghci> :l Tick.hs
Ok, modules loaded: Tick.
ghci> tick
1
2
3
...
25244
^C
Interrupted
ghci>
For a simple infinite counter just use recursion:
counter n = do print n
counter (n+1)
main = counter 1
Yet another way to implement tick functionality without using mutable state is to mix State and IO monad using monad transformers:
import Control.Monad.State
type Ticking a = StateT Int IO a
tick :: Ticking ()
tick = do
modify succ
get >>= liftIO . print
getCounterValue :: Ticking Int
getCounterValue = get
Then you can use it to create 'ticking' IO functions (with nuisance: IO functions here need to be prefixed with liftIO since it is now Ticking a monad not IO a):
ticking :: Ticking ()
ticking = do
liftIO $ putStrLn "Starting"
tick
tick
c <- getCounterValue
liftIO $ do
putStrLn ("Finished at " ++ show c)
putStrLn "Press any Enter to start infinite counter"
getChar
forever tick
Which can be converted into 'normal' IO using runStateT (with initial counter value):
startTicking :: Ticking a -> Int -> IO a
startTicking = evalStateT
So:
main :: IO ()
main = startTicking ticking 0
A forkIO safe version similar to Carl's answer using STM is
import Control.Concurrent.STM
import Control.Monad (replicateM_)
import Control.Monad(forever)
makeCounter :: IO (IO Int)
makeCounter = do
var <- newTVarIO 0
return $ do
atomically $ do
value <- readTVar var
modifyTVar var (+1)
readTVar var
-- a version that only counts from 1 to 10
main1:: IO ()
main1 = do
counter <- makeCounter
replicateM_ 10 $ counter >>= print
-- a version that counters forever
main2 :: IO ()
main2 = do
counter <- makeCounter
forever $ do
x<- counter
print x
main :: IO ()
main = do
counter <- makeCounter
tick<- counter
tick<- counter
print tick -- 2
Reference:
Mutable closures in Haskell and nested IO
An EXERCISE from STM tutorial
Mutable State in Haskell
Related
Technique for reading in multiple lines for Haskell IO
Basically I would like to find a way so that a user can enter the number of test cases and then input their test cases. The program can then run those test cases and print out the results in the order that the test cases appear. So basically I have main which reads in the number of test cases and inputs it into a function that will read from IO that many times. It looks like this: main = getLine >>= \tst -> w (read :: String -> Int) tst [[]] This is the method signature of w: w :: Int -> [[Int]]-> IO () So my plan is to read in the number of test cases and have w run a function which takes in each test case and store the result into the [[]] variable. So each list in the list will be an output. w will just run recursively until it reaches 0 and print out each list on a separate line. I'd like to know if there is a better way of doing this since I have to pass in an empty list into w, which seems extraneous.
As #bheklilr mentioned you can't update a value like [[]]. The standard functional approach is to pass an accumulator through a a set of recursive calls. In the following example the acc parameter to the loop function is this accumulator - it consists of all of the output collected so far. At the end of the loop we return it. myTest :: Int -> [String] myTest n = [ "output line " ++ show k ++ " for n = " ++ show n | k <- [1..n] ] main = do putStr "Enter number of test cases: " ntests <- fmap read getLine :: IO Int let loop k acc | k > ntests = return $ reverse acc loop k acc = do -- we're on the kth-iteration putStr $ "Enter parameter for test case " ++ show k ++ ": " a <- fmap read getLine :: IO Int let output = myTest a -- run the test loop (k+1) (output:acc) allOutput <- loop 1 [] print allOutput As you get more comfortable with this kind of pattern you'll recognize it as a fold (indeed a monadic fold since we're doing IO) and you can implement it with foldM. Update: To help explain how fmap works, here are equivalent expressions written without using fmap: With fmap: Without fmap: n <- fmap read getLine :: IO [Int] line <- getLine let n = read line :: Int vals <- fmap (map read . words) getLine line <- getLine :: IO [Int] let vals = (map read . words) line :: [Int] Using fmap allows us to eliminate the intermediate variable line which we never reference again anyway. We still need to provide a type signature so read knows what to do.
The idiomatic way is to use replicateM: runAllTests :: [[Int]] -> IO () runAllTests = {- ... -} main = do numTests <- readLn tests <- replicateM numTests readLn runAllTests tests -- or: -- main = readLn >>= flip replicateM readLn >>= runAllTests
How to monitor computation process in Haskell
I have a function in my main block map anyHeavyFunction [list] I'd like to show a progress bar during the computation process or add additional actions (pause, stop process etc.), but because map is a pure function I can't do it directly. I can guess I have to use monads, but what monad is appropriate? IO, State?
I know there is at least one library on hackage that has some pre-made monad transformers for this task, but I normally turn to the pipes package to roll my own when I need one. I am using pipes-4.0.0 it is going to be on hackage this weekend, but you can grab it form the github repo before that. I also used terminal-progress-bar package so that it makes a nice terminal animation as well. {-# language BangPatterns #-} import Pipes import qualified Pipes.Prelude as P import Control.Monad.IO.Class import System.ProgressBar import System.IO ( hSetBuffering, BufferMode(NoBuffering), stdout ) -- | Takes the total size of the stream to be processed as l and the function -- to map as fn progress l = loop 0 where loop n = do liftIO $ progressBar (msg "Working") percentage 40 n l !x <- await -- bang pattern to make strict yield x loop (n+1) main = do -- Force progress bar to print immediately hSetBuffering stdout NoBuffering let n = 10^6 let heavy x = last . replicate n $ x -- time wasting function r <- P.toListM $ each [1..100] >-> P.map heavy >-> progress 100 putStrLn "" return r This animates: > Working [=>.......................] 7% > Working [=====>...................] 20% Every update erases the last bar so it only take up one line on the terminal. Then it finishes like so: > main Working [=========================] 100% [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100]
Here's a (kind of) simple answer that I'm not satisfied with. It is based on the fact that #shellenberg wanted to apply a heavy function on each element of a (supposedly long) list. If it suffices to move the "progress bar" once for every element of the list, then the following can be turned into a general solution. First of all, you need to pick the monad in which you'll work. This depends on what exactly your "progress bar" is. For this discussion, let's say that the IO monad is enough and that we want to alternately display the characters -, /, | and \. You'll also (most probably) need some kind of state S (here it is only the number of elements processed so far, therefore S is Int), so the real monad used will be StateT S IO. Suppose your original program is: m = 100000 -- how many elements the list has -- Your (pure) function anyHeavyFunction :: Int -> Bool anyHeavyFunction n = length [1..n] + length [n+1..4217] == 4217 -- Your list list :: [Int] list = take m $ repeat 4217 -- The main program main :: IO () main = do let l = map anyHeavyFunction list if and l then putStrLn "OK" else putStrLn "WRONG" (Notice that, very conveniently, the heavy function takes the same time for each element of the list.) This is how you could convert it to display the crude "progress bar": import Control.Monad.State import System.IO (hFlush, stdout) m = 100000 -- how many elements the list has k = 5000 -- how often you want to "tick" tick :: a -> StateT Int IO a tick x = do s <- get put $ s+1 when (s `mod` k == 0) $ liftIO $ do let r = (s `div` k) `mod` 4 putChar $ "-/|\\" !! r putChar '\b' hFlush stdout x `seq` return x -- Your (pure) function anyHeavyFunction :: Int -> Bool anyHeavyFunction n = length [1..n] + length [n+1..4217] == 4217 -- Your list list :: [Int] list = take m $ repeat 4217 -- The main program main :: IO () main = do l <- flip evalStateT 0 $ mapM (tick . anyHeavyFunction) list if and l then putStrLn "OK" else putStrLn "WRONG" An interesting point: The seq in tick forces evaluation of the result for each element of the list. This is enough, if the result has a basic type (Bool here). Otherwise, it's not clear what you would want to do -- remember Haskell is lazy! If one wants a finer progress bar or if one is not satisfied with the assumption that one "tick" will be counted for each element of the list, then I believe it's necessary to incorporate the ticking in the logic of the heavy function. This makes it ugly... I'd like to see what kind of general solutions can be suggested to that. I'm all in for Haskell, but I think it just sucks for such things as progress bars... There's no free lunch; you can't be pure and lazy and have your progress bars made easy! EDIT: A version which uses the ProgressBar module suggested by #Davorak. It certainly looks nicer than my rotating bar. import Control.Monad.State import System.ProgressBar import System.IO (hSetBuffering, BufferMode(NoBuffering), stdout) m = 100000 -- how many elements the list has k = 5000 -- how often you want to "tick" tick :: a -> StateT Int IO a tick x = do s <- get put $ s+1 when (s `mod` k == 0) $ liftIO $ do progressBar (msg "Working") percentage 40 (toInteger s) (toInteger m) x `seq` return x -- Your (pure) function anyHeavyFunction :: Int -> Bool anyHeavyFunction n = length [1..n] + length [n+1..4217] == 4217 -- Your list list :: [Int] list = take m $ repeat 4217 -- The main program main :: IO () main = do hSetBuffering stdout NoBuffering l <- flip evalStateT 0 $ mapM (tick . anyHeavyFunction) list if and l then putStrLn "OK" else putStrLn "WRONG" The idea is the same, the drawbacks too.
You could use parMap to apply the expensive function in parallel (if the dependencies permit) and a list of TVars corresponding to each list (or chunk of) element(s) and set them once the respective function application has completed. A separate thread could check on the values and update the display (obviously some IO action would happen here).
How to count the number of times a function was called, the FP way
I am currently working through SICP with Haskell. Exercise 1.15 asks how many times a function is called. The idea is probably that you should use the substitution method, but I would like to know how to do so in code. In an imperative language one can keep a global variable and increment it every time the function is called. But how would you go about it in Haskell (or the pure functional way)?
You can use the Writer monad to accomplish this, provided that all of the calls to the function in question can be grouped together into a do block: import Control.Monad.Writer myFunc :: Int -> Int -> Writer (Sum Int) Int myFunc a b = tell (Sum 1) >> return (a + b) callMyFunc :: ((Int, Int, Int), Sum Int) callMyFunc = runWriter $ do a <- myFunc 2 3 b <- myFunc 8 7 c <- myFunc 3 5 return (a, b, c) main = putStrLn $ "myFunc was called " ++ show (getSum $ snd callMyFunc) ++ " times and produced " ++ show (fst callMyFunc) Which outputs: myFunc was called 3 times and produced (5,15,8)
It sounds to me like you need to have some kind of counter regardless of whether you go with a functional or a non-functional way. In Haskell, you could use the State Monad to keep track of the state: import Control.Monad.State someFunc x = do num <- get put (num + 1) return $ x * x runSomeFuncs = do someFunc 1 someFunc 2 someFunc 3 main = do let (res, state) = runState runSomeFuncs 0 putStrLn ("result: " ++ (show res)) putStrLn ("# of calls: " ++ show state) Here, you want to keep track of how many times someFunc got called, so we pass an integer in as the state and increment the integer every time the function gets called by using: num <- get put (num + 1) and then increment it by 1 and put it back. If you run this script, it should print result: 9 # of calls: 3
Project Euler 12 with Haskell's State Monad
In trying to increase my Haskell knowledge I thought I'd try and get the 12th Project Euler problem solved using the State Monad. It seemed to make sense to me at the time to incorporate the whole triangle number creation with putting it in state. Here is my code: module Main where import Control.Monad import Control.Monad.State type MyState = (Integer, Integer) s0 = (7, 28) tick :: State MyState Int tick = do (n,o) <- get let divs = getDivLen (n,o) if divs >= 500 then do let n' = n + 1 let o' = o + n' put (n', o') tick else return divs getDivLen :: MyState -> Int getDivLen (n,o) = foldl1 (+) [2 | x <- [1..x], o `mod` x == 0] where x = round . sqrt $ fromIntegral o main :: IO () main = print $ evalState tick s0 The code compiles and I get the result 6 to the console. I'm just not sure what I'm doing wrong to not have the recursion happen. Thanks in advance.
Looks like you have your loop condition backwards. You're only recursing if you've found a triangle number with at least 500 divisors, so it will of course stop immediately since the first one has fewer than that. To fix this, change the line if divs >= 500 to if divs < 500. Once you've done that, you're supposed to return the number itself, not the number of divisors, so you'll have to fix the return divs as well. I'll leave fixing that part to you.
Natural number sequence generator
As i understand Haskell does not have a global state, so is there any way to write a function f that will return f(n - 1) + 1, where n is a number of function call and f(1) = 0. It should not accept any arguments and used like func f Prelude> f () 0 Prelude> f () 1
Without using tricks like unsafePerform, it is not possible to define a function that can be called like you showed in your example. However it is possible to define an IO action that does what you want and could be used like this: Prelude> x <- f Prelude> x 0 Prelude> x <- f Prelude> x 1 Here's an example program that does what you want using IORefs: import Data.IORef main = do counter <- newIORef 0 let f = do count <- readIORef counter modifyIORef counter (+ 1) return count x <- f print x x <- f print x
You're asking for a way to update some (possibly hidden) state on each call to a procedure, such that the function returns different results given the same input. Clearly, that's no a referentially transparent function, so we must add something to Haskell's pure-by-default mode. We add notions of computation via monads. You just have to pick the monadic environment you need. The state monad The most precise way is to add just exactly the notion of state to your program, via the State monad (not to be confused with the "ST" monad): import Control.Monad.State.Strict -- a (stateful) procedure, that returns and increments an internal state counter f :: State Int Int f = do n <- get put (n+1) return n -- Call 'f' a bunch of times, print the final state. main = print $ execState code 0 where code = do f; f; f; f Now 'f' has an internal state component. Similarly, richer environments, such as IO, allow for State, so you could use the IO monad (or some other state-subsuming computational environment).
If you prefer something you can just type from the ghci command line then: Prelude> :m + Data.IORef Prelude Data.IORef> n <- newIORef 0 Prelude Data.IORef> let f = do { v <- readIORef n ; writeIORef n (v+1); return v} Prelude Data.IORef> f 0 Prelude Data.IORef> f 1 Prelude Data.IORef> f 2 Prelude Data.IORef> f 3 Your example wanted to call "f ()", but that is a C-ism that Haskell does not have. If you really want that then just change the definition of "f" to start let f _ = do {... "()" is defined in Haskell as the unit value, which is the only value of the unit type "()". You can call "f" with any argument you want; it will be ignored.
Try something like this: f 1 = 0 f n = f (n-1) + 1 EDIT: It seems I misunderstood your question; no, you cannot do something like that in haskell; functions ought to be pure. The function in your example is not pure