How to get system time in Haskell using Data.Time.Clock? - haskell

I'm needing some Ints to use as seed to random number generation and so I wanted to use the old trick of using the system time as seed.
So I tried to use the Data.Time package and I managed to do the following:
import Data.Time.Clock
time = getCurrentTime >>= return . utctDayTime
When I run time I get things like:
Prelude Data.Time.Clock> time
55712.00536s
The type of time is IO DiffTime. I expected to see an IO Something type as this depends on things external to the program. So I have two questions:
a) Is it possible to somehow unwrap the IO and get the underlying DiffTime value?
b) How do I convert a DiffTime to an integer with it's value in seconds? There's a function secondsToDiffTime but I couldn't find its inverse.

Is it possible to somehow unwrap the IO and get the underlying DiffTime value?
Yes. There are dozens of tutorials on monads which explain how. They are all based on the idea that you write a function that takes DiffTime and does something (say returning IO ()) or just returns an Answer. So if you have f :: DiffTime -> Answer, you write
time >>= \t -> return (f t)
which some people would prefer to write
time >>= (return . f)
and if you have continue :: DiffTime -> IO () you have
time >>= continue
Or you might prefer do notation:
do { t <- time
; continue t -- or possibly return (f t)
}
For more, consult one of the many fine tutorals on monads.

a) Of course it is possible to get the DiffTime value; otherwise, this function would be rather pointless. You'll need to read up on monads. This chapter and the next of Real World Haskell has a good introduction.
b) The docs for DiffTime say that it's an instance of the Real class, i.e. it can be treated as a real number, in this case the number of seconds. Converting it to seconds is thus a simple matter of chaining conversion functions:
diffTimeToSeconds :: DiffTime -> Integer
diffTimeToSeconds = floor . toRational

If you are planning to use the standard System.Random module for random number generation, then there is already a generator with a time-dependent seed initialized for you: you can get it by calling getStdGen :: IO StdGen. (Of course, you still need the answer to part (a) of your question to use the result.)

This function is not exactly what the OP asks. But it's useful:
λ: import Data.Time.Clock
λ: let getSeconds = getCurrentTime >>= return . fromRational . toRational . utctDayTime
λ: :i getSeconds
getSeconds :: IO Double -- Defined at <interactive>:56:5
λ: getSeconds
57577.607162
λ: getSeconds
57578.902397
λ: getSeconds
57580.387334

Related

How to avoid the IO monad when solving arithmetic problems in SBV

I am trying to solve arithmetic problems with SBV.
For example
solution :: SymbolicT IO ()
solution = do
[x, y] <- sFloats ["x", "y"]
constrain $ x + y .<= 2
Main> s1 = sat solution
Main> s2 = isSatisfiable solution
Main> s1
Satisfiable. Model:
x = -1.2030502e-17 :: Float
z = -2.2888208e-37 :: Float
Main> :t s1
s1 :: IO SatResult
Main> s2
True
Main> :t s2
s2 :: IO Bool
While I can do useful things, it is easier for me to work with the pure value (SatResult or Bool) and not with the IO monad.
According to the documentation
sat :: Provable a => a -> IO SatResult
constrain :: SolverContext m => SBool -> m ()
sFloats :: [String] -> Symbolic [SFloat]
type Symbolic = SymbolicT IO
Given the type of functions I use, I understand why I always get to the IO monad.
But looking in the generalized versions of the functions for example sFloats.
sFloats :: MonadSymbolic m => [String] -> m [SFloat]
Depending on type of the function, I can work with a different monad than IO. This gives me hope that we will reach a more useful monad, the Identity monad for example.
Unfortunately looking at the examples always solves the problems within the IO monad, so I couldn't find any examples that would work for me.Besides that I don't have much experience working with monads.
Finally My question is:
Is there any way to avoid the IO monad when solving such a problem with SBV?
Thanks in advance
SBV calls out to the SMT solver of your choice (most likely z3, but others are available too), and presents the results back to you. This means that it performs IO under the hood, and thus you cannot be outside the IO monad. You can create custom monads using MonadSymbolic, but that will not get you out of the IO monad: Since the call to the SMT solver does IO you'll always be in IO.
(And I'd strongly caution against uses of unsafePerformIO as suggested in one of the comments. This is really a bad idea; and you can find lots more information on this elsewhere why you shouldn't do so.)
Note that this is no different than any other IO based computation in Haskell: You perform the IO "in-the-wrapper," but once you get your results, you can do whatever you'd like to do with them in a "pure" environment.
Here's a simple example:
import Data.SBV
import Data.SBV.Control
example :: IO ()
example = runSMT $ do
[x, y] <- sFloats ["x", "y"]
constrain $ x + y .<= 2
query $ do cs <- checkSat
case cs of
Unsat -> io $ putStrLn "Unsatisfiable"
Sat -> do xv <- getValue x
yv <- getValue y
let result = use xv yv
io $ putStrLn $ "Result: " ++ show result
_ -> error $ "Solver said: " ++ show cs
-- Use the results from the solver, in a purely functional way
use :: Float -> Float -> Float
use x y = x + y
Now you can say:
*Main> example
Result: -Infinity
The function example has type IO (), because it does involve calling out to the solver and getting the results. However, once you extract those results (via calls to getValue), you can pass them to the function use which has a very simple purely functional type. So, you keep the "wrapper" in the monad, but actual processing, use-of-the values, etc., remain in the pure world.
Alternatively, you can also extract the values and continue from there:
import Data.SBV
import Data.SBV.Control
example :: IO (Maybe (Float, Float))
example = runSMT $ do
[x, y] <- sFloats ["x", "y"]
constrain $ x + y .<= 2
query $ do cs <- checkSat
case cs of
Unsat -> pure Nothing
Sat -> do xv <- getValue x
yv <- getValue y
pure $ Just (xv, yv)
_ -> error $ "Solver said: " ++ show cs
Now you can say:
*Main> Just (a, b) <- example
*Main> a
-Infinity
*Main> b
4.0302105e-21
Long story short: Don't avoid the IO monad. It's there for a very good reason. Get into it, get your results out, and then the rest of your program can remain purely functional, or whatever other monad you might find yourself in.
Note that none of this is really SBV specific. This is the usual Haskell paradigm of how to use functions with side-effects. (For instance, anytime you use readFile to read the contents of a file to process it further.) Do not try to "get rid of the IO." Instead, simply work with it.
Depending on type of the function, I can work with a different monad than IO.
Not meaningfully different, in the sense you'd hope. Every instance of this class is going to be some transformed version of IO. Sorry!
Time to make a plan that involves understanding and working with IO.

Using timeout with non-IO function haskell

I have function fun1 that is not IO and can be computationally expensive, so I want to run it for a specified amount of seconds max. I found a function timeout, but it requires this fun1 to be of IO.
timeout :: Int -> IO a -> IO (Maybe a)
How can I circumvent this, or is there a better approach to achieve my goal?
Edit:
I revised first sentence fun1 is NOT IO, it is of type fun1 :: Formula -> Bool.
Close to what talex said except moving the seq should work. Here is an example using inefficient fib as the expensive computation.
Prelude> import System.Timeout
Prelude System.Timeout> :{
Prelude System.Timeout| let fib 0 = 0
Prelude System.Timeout| fib 1 = 1
Prelude System.Timeout| fib n = fib (n-1) + fib (n-2)
Prelude System.Timeout| :}
Prelude System.Timeout> timeout 1000000 (let x = fib 44 in x `seq` return x)
Nothing
Prelude System.Timeout>
Limiting function execution to a specific time length is not pure (i.e. it does not ensure the same result every time), hence you should not be pursuing such behavior outside of IO. You can, for example, use something evil like unsafePerformIO (timeout 1000 (pure fun1)) but such usage will quickly lead to programs that are hard to understand with unexpected quirks. A better idea may be to define a custom monad that allows limited time execution and can be lifted to IO but I don't know if such a thing exists.
import System.Timeout (timeout)
import Control.Exception (evaluate)
import Control.DeepSeq (NFData, force)
timeoutPure :: Int -> a -> IO (Maybe a)
timeoutPure t = timeout t . evaluate
timeoutPureDeep :: NFData a => Int -> a -> IO (Maybe a)
timeoutPureDeep t = timeoutPure t . force
You may not want to actually write these functions, but they demonstrate the right approach. evaluate is better than seq for this sort of thing, because seq can potentially be moved around by the compiler, escaping the timeout. I'm not sure if that's actually possible in this case, but it's better to just do the thing that's sure to work than to try to analyze carefully whether the riskier approach is okay.

Randomness in a nested pure function

I want to provide a function that replaces each occurrence of # in a string with a different random number. In a non-pure language, it's trivial. However, how should it be designed in a pure language? I don't want to use unsafePerformIO, as it rather looks like a hack and not a proper design.
Should this function require a random generator as one of its parameters? And if so, would that generator have to be passed through the whole stack of invocations? Are there other possible approaches? Should I use the State monad, here? I would appreciate a toy example demonstrating a viable approach...
You would, in fact, use a variant of the state monad to pass the random generator around behind the scenes. The Rand type in Control.Monad.Random helps with this. The API is a bit confusing, but more because it's polymorphic over the type of random generator you use than because it has to be functional. This extra bit of scaffolding is useful, however, because you can easily reuse your existing code with different random generators which lets you test different algorithms as well as explicitly controlling whether the generator is deterministic (good for testing) or seeded with outside data (in IO).
Here's a simple example of Rand in action. The RandomGen g => in the type signature tells us that we can use any type of random generator for it. We have to explicitly annotate n as an Int because otherwise GHC only knows that it has to be some numeric type that can be generated and turned into a string, which can be one of multiple possible options (like Double).
randomReplace :: RandomGen g => String -> Rand g String
randomReplace = foldM go ""
where go str '#' = do
n :: Int <- getRandomR (0, 10)
return (str ++ show n)
go str chr = return $ str ++ [chr]
To run this, we need to get a random generator from somewhere and pass it into evalRand. The easiest way to do this is to get the global system generator which we can do in IO:
main :: IO ()
main = do gen <- getStdGen
print $ evalRand (randomReplace "ab#c#") gen
This is such a common pattern that the library provides an evalRandIO function which does it for you:
main :: IO ()
main = do res <- evalRandIO $ randomReplace "ab#c#"
print res
In the end, the code is a bit more explicit about having a random generator and passing it around, but it's still reasonably easy to follow. For more involved code, you could also use RandT, which allows you to extend other monads (like IO) with the ability to generate random values, letting you relegate all the plumbing and setup to one part of your code.
It's just a monadic mapping
import Control.Applicative
import Control.Monad.Random
import Data.Char
randomReplace :: RandomGen g => String -> Rand g String
randomReplace = mapM f where
f '#' = intToDigit <$> getRandomR (0, 10)
f c = return c
main = evalRandIO (randomReplace "#abc#def#") >>= print

Write list of random numbers to file. No Instance for (Show (IO a0))

I am trying to write to file a list of random Integers in a file. There seems to be a problem with writeFile here. When I use my function randomFile it says no instance for (Show (IO a0)). I see writeFile doesn't print anything to screen but IO(), so when I call the function randomFile 1 2 3 it says no Instance for Show (IO a0) but actually I just want to execute the function and not have to print anything but how can I avoid this problem. I might be making a lot of errors here. Any help.
import Control.Monad
import Control.Applicative
import System.Random
randNo mind maxd = randomRIO (mind,maxd)
randomFile mind maxd noe = do
let l=(replicate (fromInteger(noe ^ noe)) ( mind `randNo` maxd))
writeFile "RFile.txt" (show l)
I think you have a misunderstanding of what IO is. If you haven't done it, I strongly recommend going through the Input and Output section of Learn You a Haskell.
IO doesn't necessarily have anything to do with print. In Haskell every entry in memory that was made by your own code is considered "pure" while any entry that touches the rest of the computer lives in IO (with some exceptions you will learn about over time).
We model IO using something called a Monad. Which you will learn more about the longer you do Haskell. To understand this, let's look at an example of some code that does and doesn't use IO:
noIOused :: Int -> Int
noIOused x = x + 5
usesIO :: Int -> IO Int
usesIO x = print x >> return (x + 5)
usesIO2 :: Int -> IO Int
usesIO2 x = do
print x
return (x + 5)
The first function is "pure". The second and third functions have an IO "effect" that comes in the form of printing to the screen. usesIO and usesIO2 are just 2 different ways of doing the same thing (it's the same code but with different syntax). I'll use the second format, called do notation from here.
Here are some other ways you could have had IO effects:
add5WithFile :: Int -> IO Int
add5WithFile x = do
writeFile "someFile.txt" (show x)
return (x + 5)
Notice that in that function we didn't print anything, we wrote a file. But writing a file has a side effect and interacts with the rest of the system. So any value we return has to get wrapped in IO.
addRandom :: Int -> IO Int
addRandom x = do
y <- randomRIO (1,10)
return (x + y)
In addRandom we called randomRIO (1,10). But the problem is that randomRIO doesn't return an Int. It returns an IO Int. Why? Because in order to get true randomness we need to interact with the system in some way. To get around that, we have to temporarily strip away the IO. That's where this line comes in:
y <- randomRIO (1,10)
That <- arrow tells us that we want a y value outside of IO. For as long as we remain inside the do syntax that y value is going to be "pure". Now we can use it just like any other value.
So for example we couldn't do this:
let w = x + (randomRIO (1,10))
Because that would be trying to add Int to IO Int. And unfortunately our + function doesn't know how to do that. So first we have to "bind" the result of randomRIO to y before we can add it to x.
Now let's look at your code:
let l=(replicate (fromInteger(noe ^ noe)) ( mind `randNo` maxd))
writeFile "RFile.txt" (show l)
The type of l is actually IO a0. It's a0 because you haven't told the compiler what kind of number you want. So it doesn't know if you want a fraction, a double, a big integer or whatever.
So the first problem is to let the compiler know a little bit more about what kind of random number you want. We do this by adding a type annotation:
randNo :: Int -> Int -> IO Int
randNo mind maxd = randomRIO (mind,maxd)
Now both you and the compiler knows what kind of value randNo is.
Now we need to "bind" that value inside of the do notation to temporarily escape IO. You might think that would be simple, like this:
randomFile mind maxd noe = do
l <- replicate (fromInteger(noe ^ noe)) ( mind `randNo` maxd)
writeFile "RFile.txt" (show l)
Surely that will "bind" the IO Int to l right? Unfortunately not. The problem here is that replicate is a function of the form Int -> a -> [a]. That is, given a number and a type, it will give you a list of that type.
If you give replicate an IO Int it's going to make [IO Int]. That actually looks more like this: List (IO Int) except we use [] as syntactic sugar for lists. Unfortunately if we want to "bind" an IO value to something with <- it has to be the out-most type.
So what you need is a way to turn an [IO Int] into an IO [Int]. There are two ways to do that. If we put \[IO a\] -> IO \[a\] into Hoogle we get this:
sequence :: Monad m => [m a] -> m [a]
As I mentioned before, we generalise IO to something called a Monad. Which isn't really that big a deal, we could pretend that sequence has this signature: sequence :: [IO a] -> IO [a] and it would be the same thing just specialised to IO.
Now your function would be done like this:
randomFile mind maxd noe = do
l <- sequence (replicate (fromInteger(noe ^ noe)) ( mind `randNo` maxd))
writeFile "RFile.txt" (show l)
But a sequence followed by replicate is something people have to do all the time. So someone went and made a function called replicateM:
replicateM :: Monad m => Int -> m a -> m [a]
Now we can write your function like this:
randomFile mind maxd noe = do
l <- replicateM (fromInteger(noe ^ noe)) ( mind `randNo` maxd)
writeFile "RFile.txt" (show l)
And for some real Haskell magic, you can write all 3 lines of code in a single line, like this:
randomFile mind maxd noe = randomRIO >>= writeFile "RFile.txt" . replicateM (fromInteger(noe ^ noe))
If that looks like gibberish to you, then there's a lot you need to learn. Here is the suggested path:
If you haven't already, start from the beginning with Learn You a Haskell
Then learn about how You could have invented Monads
Then learn more about how to use randomness in Haskell
Finally see if you can complete the 20 intermediate Haskell exercises

Overflow problems in dealing with IO and MonadRandom and chained computations

So basically I have a computation step that takes in a previous result and outputs a Rand g Path, where Path is a custom data type (think of it like a traveling salesman kind of problem). I'm letting MonadRandom handle all of the generator passing and stuff.
I want to find the, say, nth composition of this computation upon itself. Right now I'm using
thecomputation :: (RandomGen g) => Rand g Path
thecomputation = (iterate (>>= step) (return startingPath)) !! n
And then to print it out I would run
main = do
res <- evalRandIO thecomputation
print res
However, I have a problem
If I pick a high enough n (i need on the order of 10^6), I get a stack overflow.
I've managed to track the problem to the fact that thecomputation is actually a heavily composed (nested?) IO object. It's a series of IO computations and so ghc has to keep track of all of those layers of nested IO's, and after enough layers, it gives up.
How am I supposed to deal with this? In an imperative language there really isn't much to this. But what should I do here? Should I force some of the IO's to evaluate or ...?
There is a similar question on this site but I wasn't able to get anything helpful out of the accepted answer so I'm still pretty lost
Concrete Example
import System.Random
import Control.Monad.Random
import Control.Monad
data Path = DoublePath Double deriving Show
step :: (RandomGen g) => Path -> Rand g Path
step (DoublePath x) = do
dx <- getRandom
return (DoublePath ((x + dx)/x))
thecomputation :: (RandomGen g) => Rand g Path
thecomputation = (iterate (>>= step) (return (DoublePath 10.0))) !! 1000000
main = do
result <- evalRandIO thecomputation
print result
does overflow on my computer
You are bitten by lazyness: Everytime you call step on some value x, GHC is creating a thunk step x that is not evaluated until the final value is required.
A simple fix is to make step strict in its argument, e.g. by pattern-matching on DoublePath !x (and using -XBangPatterns) or inserting x `seq` before the body of the function. Then your code finished without stack overflow (heh).
It is enough to make the type strict. This ought to be second nature especially for numerical and other 'unboxable' parameters and doesn't require a language extension.
data Path = DoublePath !Double deriving Show
-- $ ghc -O2 doublepath.hs
-- ...
-- $ time ./doublepath
-- DoublePath 1.526581416150007
-- real 0m2.516s
-- user 0m2.307s
-- sys 0m0.092s

Resources