To avoid CAF (resource sharing), I tried converting to function
with dummy argument, but no success (noCafB).
I've read How to make a CAF not a CAF in Haskell? so tried noCafC and noCafD. When compiled with
-O0, then functions with dummy argument did evaluated every time.
However, with -O2, it seems that GHC converts those functions to
CAF. Is this intended behaviour (GHC's optimization)?
module Main where
import Debug.Trace
cafA :: [Integer]
cafA = trace "hi" (map (+1) $ [1..])
noCafB :: a -> [Integer]
noCafB _ = trace "hi" (map (+1) $ [1..])
noCafC :: a -> [Integer]
noCafC _ = trace "hi" (map (+1) $ [1..])
{-# NOINLINE noCafC #-}
noCafD :: a -> [Integer]
noCafD _ = trace "hi" (map (+1) $ myEnumFrom 0 1)
{-# NOINLINE noCafD #-}
myEnumFrom :: a -> Integer -> [Integer]
myEnumFrom _ n = enumFrom n
{-# NOINLINE myEnumFrom #-}
main :: IO ()
main = do
putStrLn "cafA"
print $ (cafA !! 1 + cafA !! 2)
putStrLn "noCafB"
print $ (noCafB 0 !! 1 + noCafB 0 !! 2)
putStrLn "noCafC"
print $ (noCafC 0 !! 1 + noCafC 0 !! 2)
putStrLn "noCafD"
print $ (noCafD 0 !! 1 + noCafD 0 !! 2)
Result with -O2
$ stack ghc -- --version
The Glorious Glasgow Haskell Compilation System, version 7.10.3
$ stack ghc -- -O2 cafTest.hs
[1 of 1] Compiling Main ( cafTest.hs, cafTest.o )
Linking cafTest ...
$ ./cafTest
cafA
hi
7
noCafB
7
noCafC
7
noCafD
hi
7
Result with -O0
$ stack ghc -- -O0 cafTest.hs
[1 of 1] Compiling Main ( cafTest.hs, cafTest.o )
Linking cafTest ...
$ ./cafTest
cafA
hi
7
noCafB
hi
hi
7
noCafC
hi
hi
7
noCafD
hi
hi
7
I've also tried without trace but results was same. under -O2, I found that the result of incInt function is shared by inspecting profiling output. Why this behaviour?
incIntOrg :: [Integer]
incInt = map (+1) [1..]
incInt :: a -> [Integer] -- results IS shared. should it be?
incInt _ = map (+1) $ myEnum 0 1
{-# NOINLINE incInt #-}
myEnum :: a -> Integer -> [Integer]
myEnum _ n = enumFrom n
{-# NOINLINE myEnum #-}
main :: IO ()
main = do
print (incInt 0 !! 9999999)
print (incInt 0 !! 9999999)
print (incInt 0 !! 9999999)
Any comments will be appreciated deeply. Thanks.
Related
I'm a newbie so I'm having problems doing this:P
Currently I have tried this:
xs1 :: RandomGen g => Int -> g -> [[Char]]
xs1 n = sequence $ replicate n $ randomRs ('!', '~' ::Char)
but I can't give this string to my function:
fun1 :: (Eq a, Num a) => [a] -> [Char] -> [Char]
fun1 a xs1=[if (a!!n==1) then (xs1!!n) else b | n <- [0, 1,2,3,4]]
any help would be greatly appreciated
IMO the easiest way for a beginner to use random stuff is randomIO or randomRIO - here is an example printing 5 random characters (in the range '!' to '~'):
import Control.Monad (replicateM)
import System.Random (Random(randomRIO))
randomString :: Int -> IO String
randomString len = replicateM len $ randomRIO ('!', '~')
select :: (Num f, Eq f) => [f] -> String -> String
select =
zipWith (\f c -> if f == 1 then c else ' ')
main :: IO ()
main = do
-- there will be a warning without the `:: Int`
s <- select [1 :: Int,0,1,0,1] <$> randomString 5
putStrLn s
I'm using randomRIO here because using just randomIO will give you random characters from all over the place most likely all unprintable ;)
I don't know what you are trying to do with fun1 but I'll gone edit if you make it clear
How can I randomly generate a string 5 symbols long ?
Due to the use of randomRs, your xs1 function returns a list of infinitely long strings.
Also, as xs1 is a function not a list, you cannot really index it thru the !! operator.
Please please: paste the full text of the error message in your question, rather than just writing:
“I can't give this string to my function:”.
In order to generate random strings, you need two things:
a generator, typically returned by mkStdGen or mkTFGen
a monadic action object with the appropriate return type
Let's try to do that under the ghci Haskell interpreter:
$ ghci
GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help
λ>
λ> import System.Random
λ> import Control.Monad.Random
λ>
So let's get a generator first:
λ>
λ> seed = 42
λ> gen1 = mkStdGen seed
λ>
Then let's write the action object:
λ>
λ> act5 = sequence $ replicate 5 (getRandomR ('!', '~' ::Char))
λ>
λ> :type act5
act5 :: MonadRandom m => m [Char]
λ>
The action object is essentially a wrapper around a transition function that takes a generator and returns some (output value, new generator) pair.
Finally, we combine these two things thru the runRand :: Rand g a -> g -> (a, g) library function, which returns both the value you want and an updated generator:
λ>
λ> (str1, gen2) = runRand act5 gen1
λ>
λ> str1
"D6bK/"
λ>
And we can even get a second pseudo-random string, courtesy of the updated generator:
λ>
λ> (str2, gen3) = runRand act5 gen2
λ>
λ> str2
"|}#5h"
λ>
And so on ... As you can see, it is not really necessary to use the IO monad for this.
A slight generalization:
Now, say you need 6 such random strings:
λ>
λ> act5rep = sequence (replicate 6 act5)
λ>
λ> :type act5rep
act5rep :: MonadRandom m => m [[Char]]
λ>
λ> (strs, newGen) = runRand act5rep gen1
λ>
λ> strs
["D6bK/","|}#5h","0|qSQ","h4:.1","3+e-}","}eu,I"]
λ>
I am writing a function that generates a million random numbers of 1 or 0 and then counts how many 0s were generated.
import System.Random
import Control.Monad
countZeros :: Int -> IO Int
countZeros n = (length . filter (==0)) <$> (replicateM n $ randomRIO (0,1 :: Int))
countZeros' :: Int -> IO Int
countZeros' n = go n 0
where
go :: Int -> Int -> IO Int
go x acc = do
r <- randomRIO (0,1 :: Int)
case x of
0 -> pure acc
_ -> let acc' = if r == 0 then succ acc else acc
in go (pred x) acc'
when I run the functions with an input of 1000000
>λ= countZeros 1000000
499716
(0.93 secs, 789,015,080 bytes)
>λ= countZeros' 1000000
500442
(2.02 secs, 1,109,569,560 bytes)
I don't understand why the prime function is twice as slow as the other. I assumed that they are essentially doing the same thing behind the scenes.
I am using GHCi.
What am I missing?
With bang patterns, and proper compilation with -O2, the "prime" function is faster:
{-# LANGUAGE BangPatterns #-}
module Main where
import System.Random
import Control.Monad
import System.Environment
countZeros :: Int -> IO Int
countZeros n = (length . filter (==0)) <$> (replicateM n $ randomRIO (0,1 :: Int))
countZeros' :: Int -> IO Int
countZeros' n = go n 0
where
go :: Int -> Int -> IO Int
go !x !acc = do
r <- randomRIO (0,1 :: Int)
case x of
0 -> pure acc
_ -> let acc' = if r == 0 then succ acc else acc
in go (pred x) acc'
main :: IO ()
main = do
[what] <- getArgs
let n = 1000 * 1000 * 10
fun = case what of
"1" -> countZeros
"2" -> countZeros'
_ -> error "arg not a number"
putStrLn "----"
print =<< fun n
putStrLn "----"
Compiled with
$ stack ghc -- RandomPerf.hs -O2 -Wall
$ stack ghc -- --version
The Glorious Glasgow Haskell Compilation System, version 8.6.3
Tests:
$ time ./RandomPerf.exe 1
----
4999482
----
real 0m3.329s
user 0m0.000s
sys 0m0.031s
$ time ./RandomPerf.exe 2
----
5001089
----
real 0m2.338s
user 0m0.000s
sys 0m0.046s
Repeating the tests gives comparable results, so this is not a fluke.
Result: the countZeros' function is significantly faster.
Using Criterion and running a proper benchmark is left as an exercise.
You probably used GHCi to assess performance, which prevents the optimizer to do its job. GHCi sacrifices proper optimization to load files faster, and be more usable in an interactive way.
These actually work in different ways from each other, at a level that matters. And both are slow.
The version using replicateM is bad because replicateM in IO can't stream its results. The entire list will be constructed at once, before filter and length get to start operating on it. The reason it's faster is that length is strict in its accumulator, so it doesn't generate a massive nested chain of thinks the way your other version does. And that's even worse for performance.
The recursive version doesn't use a strict accumulator. This means that the value it returns is a giant chain of nested thunks, holding on to all the generated entries and a bunch of indirect calls via list indexing. This is even more memory used than the filter version, because it's holding on to a bunch of closures as well as all the values. But even with that fixed, it would still be slow. Using !! just wrecks performance. It's recursive when a simple if would do the same job much more efficiently.
I've written a small program to find the prime factorization of a number. Everything seems to compile except for the main function, which complains about not being able to find a Show1 instance.
{-# LANGUAGE DeriveFunctor #-}
module FactorAnamorphism where
import Data.Functor.Foldable
import Data.List
nextPrimeFactor :: Integer -> Maybe Integer
nextPrimeFactor n = find (\x -> n `mod` x /= 0) [2..(floor $ sqrt $ fromIntegral n)]
data ExprF r = FactorF Integer | MultF r r deriving (Show, Functor)
type Expr = Fix ExprF
factor :: Integer -> Expr
factor = ana coAlg where
coAlg fac = case (nextPrimeFactor fac) of
Just prime -> MultF prime (fac `div` prime)
Nothing -> FactorF fac
main :: IO ()
main = putStrLn $ show $ factor 10
Logs:
% stack build
haskell-playground-0.1.0.0: build (lib + exe)
Preprocessing library haskell-playground-0.1.0.0...
Preprocessing executable 'factor-anamorphism' for
haskell-playground-0.1.0.0...
[1 of 1] Compiling FactorAnamorphism ( app/FactorAnamorphism.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/factor-anamorphism/factor-anamorphism-tmp/FactorAnamorphism.o )
/Users/ian/proj/macalinao/haskell-playground/app/FactorAnamorphism.hs:22:19: error:
• No instance for (Data.Functor.Classes.Show1 ExprF)
arising from a use of ‘show’
• In the second argument of ‘($)’, namely ‘show $ factor 10’
In the expression: putStrLn $ show $ factor 10
In an equation for ‘main’: main = putStrLn $ show $ factor 10
-- While building package haskell-playground-0.1.0.0 using:
/Users/ian/.stack/setup-exe-cache/x86_64-osx/Cabal-simple_mPHDZzAJ_1.24.2.0_ghc-8.0.2 --builddir=.stack-work/dist/x86_64-osx/Cabal-1.24.2.0 build lib:haskell-playground exe:factor-anamorphism exe:haskell-playground-exe --ghc-options " -ddump-hi -ddump-to-file"
Process exited with code: ExitFailure 1
The instance of Show for Fix is: Show1 f => Show (Fix f), which is why the compiler expects Show1 ExprF.
Show1 can be found in base under Data.Functor.Classes, and there is a TH script to derive it in Text.Show.Deriving from deriving-compat.
I've written the code below, and noticed that killThread blocks and the thread still continues. That only happens if I do it in the forkProcess, if I remove the forkProcess, everything works as expected.
Code
{-# LANGUAGE TupleSections #-}
module Main where
import Control.Concurrent
import Control.Monad
import System.Posix.Process
{-# NOINLINE primes #-}
primes :: [Integer]
primes = 2:[x | x <- [3..], all (not . flip isDivisorOf x) (takeWhile (< truncate (sqrt $ fromInteger x :: Double)) primes)]
where x `isDivisorOf` y = y `rem` x == 0
evaluator :: Show a => [a] -> IO ()
evaluator xs = do
putStrLn "[Evaluator] Started evaluator."
forM_ xs $ \x -> putStrLn $ "[Evaluator] Got result: " ++ show x
putStrLn "[Evaluator] Evaluator exited."
test :: IO ThreadId
test = forkIO (evaluator $ filter ((== 13) . flip rem (79 * 5 * 7 * 3 * 3 * 2 * 3)) primes) -- Just some computation that doesn't finsish too fast
main :: IO ()
main = do
pid <- forkProcess $ do
a <- test
threadDelay $ 4000 * 1000
putStrLn "Canceling ..."
killThread a
putStrLn "Canceled"
void $ getProcessStatus True False pid
Output
$ ghc test.hs -O -fforce-recomp -threaded -eventlog -rtsopts # I also tried with -threaded
$ ./test +RTS -N2 # I also tried without -N
[Evaluator] Started evaluator.
[Evaluator] Got result: 13
[Evaluator] Got result: 149323
[Evaluator] Got result: 447943
[Evaluator] Got result: 597253
[Evaluator] Got result: 746563
[Evaluator] Got result: 1045183
Canceling ...
[Evaluator] Got result: 1194493
[Evaluator] Got result: 1642423
[Evaluator] Got result: 1791733
[Evaluator] Got result: 2090353
[Evaluator] Got result: 2687593
[Evaluator] Got result: 3135523
[Evaluator] Got result: 3284833
[Evaluator] Got result: 4777933
[Evaluator] Got result: 5375173
^C[Evaluator] Got result: 5524483
^C
This is not the usual problem that there is no memory allocation and thus GHC's thread scheduler doesn't run. I verified that by running the program with +RTS -sstderr, which shows that the garbage collector is running very often. I'm running this on linux 64bit.
This bug report notes that forkProcess masks asynchronous exceptions in the child process despite no indication of such in the documentation. The behavior should be fixed in 7.8.1 when it is released.
Of course, if asynchronous exceptions are masked, the throw inside the killThread will block indefinitely. If you simply delete the lines in main containing forkProcess and getProcessStatus, the program works as intended:
module Main where
import Control.Concurrent
import Control.Monad
import System.Posix.Process
{-# NOINLINE primes #-}
primes :: [Integer]
primes = 2:[ x | x <- [3..], all (not . flip isDivisorOf x) (takeWhile (< truncate (sqrt $ fromInteger x :: Double)) primes)]
where x `isDivisorOf` y = y `rem` x == 0
evaluator :: Show a => [a] -> IO ()
evaluator = mapM_ $ \x ->
putStrLn $ "[Evaluator] Got result: " ++ show x
test :: IO ThreadId
test = forkIO (evaluator $ filter ((== 13) . flip rem (79 * 5 * 7 * 3 * 3 * 2 * 3)) primes) -- Just some computation that doesn't finsish too fast
main :: IO ()
main = do
a <- test
threadDelay $ 4000 * 1000
putStrLn "Canceling ..."
killThread a
putStrLn "Canceled"
I build it with ghc --make -threaded async.hs and run with ./async +RTS -N4.
If for some reason you need a separate process, you will have to manually unmask asynchronous exceptions in the child process in GHC 7.6.3.
I get the following error when trying to compile
$ ghc --make -O2 -Wall -fforce-recomp
[1 of 1] Compiling Main (
isPrimeSmart.hs, isPrimeSmart.o )
SpecConstr
Function `$wa{v s2we} [lid]'
has two call patterns, but the limit is 1
Use -fspec-constr-count=n to set the bound
Use -dppr-debug to see specialisations Linking isPrimeSmart
...
My code is:
{-# OPTIONS_GHC -O2 -optc-O2 #-}
import qualified Data.ByteString.Lazy.Char8 as StrL -- StrL is STRing Library
import Data.List
-- read in a file. First line tells how many cases. Each case is on a separate
-- line with the lower an upper bounds separated by a space. Print all primes
-- between the lower and upper bound. Separate results for each case with
-- a blank line.
main :: IO ()
main = do
let factors = takeWhile (<= (ceiling $ sqrt (1000000000::Double))) allPrimes
(l:ls) <- StrL.lines `fmap` StrL.getContents
let numCases = readInt l
let cases = (take numCases ls)
sequence_ $ intersperse (putStrLn "") $ map (doLine factors) cases
-- get and print all primes between the integers specified on a line.
doLine :: [Integer] -> StrL.ByteString -> IO ()
doLine factors l = mapM_ print $ primesForLine factors l
---------------------- pure code below this line ------------------------------
-- get all primes between the integers specified on a line.
primesForLine :: [Integer] -> StrL.ByteString -> [Integer]
primesForLine factors l = getPrimes factors range
where
range = rangeForLine l
-- Generate a list of numbers to check, store it in list, and then check them...
getPrimes :: [Integer] -> (Integer, Integer) -> [Integer]
getPrimes factors range = filter (isPrime factors) (getCandidates range)
-- generate list of candidate values based on upper and lower bound
getCandidates :: (Integer, Integer) -> [Integer]
getCandidates (propStart, propEnd) = list
where
list = if propStart < 3
then 2 : oddList
else oddList
oddList = [listStart, listStart + 2 .. propEnd]
listStart = if cleanStart `rem` 2 == 0
then cleanStart + 1
else cleanStart
cleanStart = if propStart < 3
then 3
else propStart
-- A line always has the lower and upper bound separated by a space.
rangeForLine :: StrL.ByteString -> (Integer, Integer)
rangeForLine caseLine = start `seq` end `seq` (start, end)
where
[start, end] = (map readInteger $ StrL.words caseLine)::[Integer]
-- read an Integer from a ByteString
readInteger :: StrL.ByteString -> Integer
readInteger x =
case StrL.readInteger x of Just (i,_) -> i
Nothing -> error "Unparsable Integer"
-- read an Int from a ByteString
readInt :: StrL.ByteString -> Int
readInt x =
case StrL.readInt x of Just (i,_) -> i
Nothing -> error "Unparsable Int"
-- generates all primes in a lazy way.
allPrimes :: [Integer]
allPrimes = ps (2:[3,5 .. ])
where
ps (np:candidates) = -- np stands for New Prime
np : ps (filter (\n -> n `rem` np /= 0) candidates)
ps [] = error "this can't happen but is shuts up the compiler"
-- Check to see if it is a prime by comparing against the factors.
isPrime :: [Integer] -> Integer -> Bool
isPrime factors val = all (\f -> val `rem` f /= 0) validFactors
where
validFactors = takeWhile (< ceil) factors
ceil = ((ceiling $ sqrt $ ((fromInteger val)::Double))) :: Integer
I have no idea how to fix this warning. How do I start? Do I compile to assembly and match the error up? What does the warning even mean?
These are just (annoying) warnings, indicating that GHC could do further specializations to your code if you really want to. Future versions of GHC will likely not emit this data by default, since there's nothing you can do about it anyway.
They are harmless, and are not errors. Don't worry about them.
To directly address the problem, you can use -w (suppress warnings) instead of -Wall.
E.g. in a file {-# OPTIONS_GHC -w #-} will disable warnings.
Alternately, increasing the specialization threshold will make the warning go away, e.g. -fspec-constr-count=16