I have written the following code in Haskell:
import Data.IORef
import Control.Monad
import Control.Monad.Trans.Cont
import Control.Monad.IO.Class
fac n = do
i<-newIORef 1
f<-newIORef 1
replicateM_ n $ do
ri<-readIORef i
modifyIORef f (\x->x*ri)
modifyIORef i (+1)
readIORef f
This is very nice code which implements factorial as an imperative function. But replicateM_ cannot fully simulate the use of a real for loop. So I tried to create something using continuations but I have failed here is my code:
ff = (`runContT` id) $ do
callCC $ \exit1 -> do
liftIO $ do
i<-newIORef 1
f<-newIORef 1
callCC $ \exit2 -> do
liftIO $ do
ri<-readIORef i
modifyIORef (\x->x*ri)
modifyIORef i (+1)
rri<-readIORef i
when (rri<=n) $ exit2(())
liftIO $ do
rf<-readIORef f
return rf
Can you help me correct my code?
Thanks
Since your a beginner to Haskell and not doing this simply to learn how continuations and IORefs work, you're doing it wrong.
The Haskell-y way to write an imperative loop is tail-calls or folds.
factorial n = foldl1' (*) [1..n]
factorial' n = go 1 n
where go accum 0 = accum
go accum n = go (n-1) (accum * n)
Also since Haskell's callCC in essence provides you an early return, using it to simulate loops is not going to work.
callCC (\c -> ???)
Think about what we would have to put in for ??? in order to loop. somehow, we want to run callCC again if it returns a certain value, otherwise just keep going on our merry way.
But nothing we put in ??? can make the callCC run again! It's going to return a value no matter what we do. So instead we'll need to do something around that callCC
let (continue, val) = callCC (someFunc val)
in if continue
then callCallCCAgain val
else val
Something like this right? But wait, callCallCCAgain is recursion! It's even tail recursion! In fact, that callCC is doing no one any good
loop val = let (continue, val') = doBody val
in if continue
then loop val'
else val'
Look familiar? This is the same structure as factorial' above.
You can still use IORefs and something like the monad-loops package, but it's going to be an uphill battle always because Haskell isn't meant to be written like that.
Summary
When you want to directly do "loops" in haskell, use tail recursion. But really, try to use combinators like fold and map, they're like little specialized loops and GHC is fantastic at optimizing them. And definitely don't use IORefs, trying to program Haskell like it's C is just going to hurt your performance, readability, and everyone will be sad.
Related
I'm trying to write code in source -> transform -> sink style, for example:
let (|>) = flip ($)
repeat 1 |> take 5 |> sum |> print
But would like to do that using IO. I have this impression that my source can be an infinite list of IO actions, and each one gets evaluated once it is needed downstream. Something like this:
-- prints the number of lines entered before "quit" is entered
[getLine..] >>= takeWhile (/= "quit") >>= length >>= print
I think this is possible with the streaming libraries, but can it be done along the lines of what I'm proposing?
Using the repeatM, takeWhile and length_ functions from the streaming library:
import Streaming
import qualified Streaming.Prelude as S
count :: IO ()
count = do r <- S.length_ . S.takeWhile (/= "quit") . S.repeatM $ getLine
print r
This seems to be in that spirit:
let (|>) = flip ($)
let (.>) = flip (.)
getContents >>= lines .> takeWhile (/= "quit") .> length .> print
The issue here is that Monad is not the right abstraction for this, and attempting to do something like this results in a situation where referential transparency is broken.
Firstly, we can do a lazy IO read like so:
module Main where
import System.IO.Unsafe (unsafePerformIO)
import Control.Monad(forM_)
lazyIOSequence :: [IO a] -> IO [a]
lazyIOSequence = pure . go where
go :: [IO a] -> [a]
go (l:ls) = (unsafePerformIO l):(go ls)
main :: IO ()
main = do
l <- lazyIOSequence (repeat getLine)
forM_ l putStrLn
This when run will perform cat. It will read lines and output them. Everything works fine.
But consider changing the main function to this:
main :: IO ()
main = do
l <- lazyIOSequence (map (putStrLn . show) [1..])
putStrLn "Hello World"
This outputs Hello World only, as we didn't need to evaluate any of l. But now consider replacing the last line like the following:
main :: IO ()
main = do
x <- lazyIOSequence (map (putStrLn . show) [1..])
seq (head x) putStrLn "Hello World"
Same program, but the output is now:
1
Hello World
This is bad, we've changed the results of a program just by evaluating a value. This is not supposed to happen in Haskell, when you evaluate something it should just evaluate it, not change the outside world.
So if you restrict your IO actions to something like reading from a file nothing else is reading from, then you might be able to sensibly lazily evaluate things, because when you read from it in relation to all the other IO actions your program is taking doesn't matter. But you don't want to allow this for IO in general, because skipping actions or performing them in a different order can matter (and above, certainly does). Even in the reading a file lazily case, if something else in your program writes to the file, then whether you evaluate that list before or after the write action will affect the output of your program, which again, breaks referential transparency (because evaluation order shouldn't matter).
So for a restricted subset of IO actions, you can sensibly define Functor, Applicative and Monad on a stream type to work in a lazy way, but doing so in the IO Monad in general is a minefield and often just plain incorrect. Instead you want a specialised streaming type, and indeed Conduit defines Functor, Applicative and Monad on a lot of it's types so you can still use all your favourite functions.
Excuse me if this is a really dumb question, but I've read through one book and most of another book on Haskell already and don't seem to remember anywhere this was brought up.
How do I do the same thing n times? If you want to know exactly what I am doing, I'm trying to do some of the Google Code Jam questions to learn Haskell, and the first line of the input gives you the number of test cases. That being the case, I need to do the same thing n times where n is the number of test cases.
The only way I can think of to do this so far is to write a recursive function like this:
recFun :: Int -> IO () -> IO ()
recFun 0 f = do return ()
recFun n f = do
f
recFun (n-1) f
return ()
Is there no built in function that already does this?
forM_ from Control.Monad is one way.
Example:
import Control.Monad (forM_)
main = forM_ [1..10] $ \_ -> do
print "We'll do this 10 times!"
See the documentation here
http://hackage.haskell.org/package/base-4.8.0.0/docs/Control-Monad.html#v:forM-95-
I have been experimenting with the strict and lazy ST monads, and I do not understand clearly the degree of laziness of each.
For example, using the lazy Control.Monad.State.Lazy monad we can write:
main = print $ (flip evalState) "a" $ do
forever $ put "b"
put "c"
get
This works fine and outputs "c". Dually, the same code for the strict Control.Monad.State.Strict variant will run put "b" forever, and hang.
Intuitively, I would expect the same duality to hold for the ST monads. That is, given the code:
main = print $ S.runST $ do
r <- newSTRef "a"
forever $ writeSTRef r "b"
writeSTRef r "c"
readSTRef r
Control.Monad.ST.Lazy should output "c", while Control.Monad.ST.Strict should hang. However, they both loop indefinitely. I believe that there is a valid reason for this, like: reading backwards, the reference r is not yet allocated at the time that the last writeSTRef is called. But it somehow feels like we could do better.
How lazy is the lazy Control.Monad.ST.Lazy monad?
Surprisingly, it is perfectly lazy. But Data.STRef.Lazy isn't.
ST.Lazy is lazy
Lets focus on another example for a second:
import qualified Control.Monad.ST as S
import qualified Control.Monad.ST.Lazy as L
squared :: Monad m => m [Integer]
squared = mapM (return . (^2)) [1..]
ok, oops :: [Integer]
ok = L.runST squared
oops = S.runST squared
Even though ok and oops should do the same, we can get only the elements of ok. If we would try to use head oops, we would fail. However, concerning ok, we can take arbitrarily many elements.
Or, to compare them to the non-monadic squared list, they behave like:
ok, oops :: [Integer]
ok' = map (^2) [1..]
oops' = let x = map (^2) [1..] in force x -- Control.DeepSeq.force
That's because the strict version evaluates all state operations, even though they're not required for our result. On the other hand, the lazy version delays the operations:
This module presents an identical interface to Control.Monad.ST, except that the monad delays evaluation of state operations until a value depending on them is required.
What about readSTRef?
Now lets focus again on your example. Note that we can get an infinite loop with even simpler code:
main = print $ L.runST $ do
forever $ return ()
r <- newSTRef "a"
readSTRef r
If we add an additional return at the end …
main = print $ L.runST $ do
forever $ return ()
r <- newSTRef "a"
readSTRef r
return "a"
… everything is fine. So apparently there's something strict in newSTRef or readSTRef. Lets have a look at their implementation:
import qualified Data.STRef as ST
newSTRef = strictToLazyST . ST.newSTRef
readSTRef = strictToLazyST . ST.readSTRef
writeSTRef r a = strictToLazyST (ST.writeSTRef r a)
And there's the culprit. Data.STRef.Lazy is actually implemented via Data.STRef, which is meant for Control.Monad.ST.Strict. strictToLazyST only hides this detail:
strictToLazyST :: ST.ST s a -> ST s a
strictToLazyST m = ST $ \s ->
Convert a strict ST computation into a lazy one. The strict state thread passed to strictToLazyST is not performed until the result of the lazy state thread it returns is demanded.
Now lets put things together:
in main, we want to print the value given by the lazy ST computation
the lazy ST computation's value is given by a lazy readSTRef
the lazy readSTRef is actually implemented as a lazy wrapper around the strict readSTRef
the strict readSTRef evaluates the state as if it was a strict one
the strict evaluation of forever $ return () bites us
So the current ST.Lazy is lazy enough. It's the Data.STRef.Lazy that's too strict. As long as Data.STRef.Lazy is based on strictToLazyST, this behavior will endure.
I have following problem: Given a [String] and String->IO Int. So I can make a transformation (map) and get [IO Int]. Now, I have to do two things -- perfrorm that actions, from start, until result is positive and I need to know, was all list processed.
I am forbidded to process after first non-positive result.
takeWhileM do not answer second question(length compraison is too impractical), and spanM perform forbidden IO.
Of course, I can write recursive function myself, but I want to do it in Haskell way, with all good of high-order functions.
Suggestions? Probably, use completely another approach?
Task above is a bit simplified task from my project.
You can use allM from the monad-loops package:
Prelude Control.Monad.Loops> let xs = ["a", "bb", "ccc", "dddd", "eeeee"]
Prelude Control.Monad.Loops> let f x = putStrLn x >> return (length x)
Prelude Control.Monad.Loops> let p x = x < 2
Prelude Control.Monad.Loops> allM (fmap p . f) xs
a
bb
False
There's also an allM in Control.Monad.ListM, but it's not appropriately lazy—it will continue to perform computations after you hit a positive result.
(I'm with you on this, by the way—I hate writing one-off recursive functions.)
I'm not familiar with the functions takeWhileM and spanM (and neither is hoogle) (edit: as per comment, they can be found in Control.Monad.ListM).
Given that, I think the best thing for you to do is to make a one-off function to perform this task. If it later turns out that you need to write code to do something similar, then you can factor out the common parts and re-use them. There's nothing wrong with writing one-off code in general, it's code duplication that's bad.
There are a few ways to write the function you want - one possible way is like this:
process :: [IO Int] -> IO Bool
process [] = return True
process [a] = a >> return True
process (a:as) = do
n <- a
if n > 0
then return False
else process as
#illusionoflife: I don't see how using takeWhileM would improve on #Chris's solution.
For example:
import Control.Monad.ListM
process :: [IO Int] -> IO Bool
process as = do
taken <- takeWhileM (>>= return . (<= 0)) as
return (length taken >= length as - 1)
(Code not verified!)
#Chris's looks more readable, among other things because in his solution we don't need to figure out if we should use >= or ==. Besides, since I call length we can't use it on an infinite input list.
I am trying to parse an input stream where the first line tells me how many lines of data there are. I'm ending up with the following code, and it works, but I think there is a better way. Is there?
main = do
numCases <- getLine
proc $ read numCases
proc :: Integer -> IO ()
proc numCases
| numCases == 0 = return ()
| otherwise = do
str <- getLine
putStrLn $ findNextPalin str
proc (numCases - 1)
Note: The code solves the Sphere problem https://www.spoj.pl/problems/PALIN/ but I didn't think posting the rest of the code would impact the discussion of what to do here.
Use replicate and sequence_.
main, proc :: IO ()
main = do numCases <- getLine
sequence_ $ replicate (read numCases) proc
proc = do str <- getLine
putStrLn $ findNextPalin str
sequence_ takes a list of actions, and runs them one after the other, in sequence. (Then it throws away the results; if you were interested in the return values from the actions, you'd use sequence.)
replicate n x makes a list of length n, with each element being x. So we use it to build up the list of actions we want to run.
Dave Hinton's answer is correct, but as an aside here's another way of writing the same code:
import Control.Applicative
main = (sequence_ . proc) =<< (read <$> getLine)
proc x = replicate x (putStrLn =<< (findNextPalin <$> getLine))
Just to remind everyone that do blocks aren't necessary! Note that in the above, both =<< and <$> stand in for plain old function application. If you ignore both operators, the code reads exactly the same as similarly-structured pure functions would. I've added some gratuitous parentheses to make things more explicit.
Their purpose is that <$> applies a regular function inside a monad, while =<< does the same but then compresses an extra layer of the monad (e.g., turning IO (IO a) into IO a).
The interesting part of looking at code this way is that you can mostly ignore where the monads and such are; typically there's very few ways to place the "function application" operators to make the types work.
You (and the previous answers) should work harder to divide up the IO from the logic. Make main gather the input and separately (purely, if possible) do the work.
import Control.Monad -- not needed, but cleans some things up
main = do
numCases <- liftM read getLine
lines <- replicateM numCases getLine
let results = map findNextPalin lines
mapM_ putStrLn results
When solving SPOJ problems in Haskell, try not to use standard strings at all. ByteStrings are much faster, and I've found you can usually ignore the number of tests and just run a map over everything but the first line, like so:
{-# OPTIONS_GHC -O2 -optc-O2 #-}
import qualified Data.ByteString.Lazy.Char8 as BS
main :: IO ()
main = do
(l:ls) <- BS.lines `fmap` BS.getContents
mapM_ findNextPalin ls
The SPOJ page in the Haskell Wiki gives a lot of good pointers about how to read Ints from ByteStrings, as well as how to deal with a large quantities of input. It'll help you avoid exceeding the time limit.