open import Agda.Builtin.Int
open import Prelude
postulate randomRIO : Int → Int → IO Int
{-# FOREIGN GHC import qualified System.Random as Random #-}
{-# COMPILE GHC randomRIO = \a -> \b -> Random.randomRIO (a, b) #-}
main : IO Unit
main = do
num ← randomRIO 1 10
putStrLn $ show num
I imported haskell function randomRIO into Agda. I think output range of randomRIO is determined by first two arguments a and b, like a <= (return value) <= b. But I can't make these types from nothing. To make these types, it have to get some type information of return type. But randomIO is foreign function, I can't get any information of return type.
Is there way to define range of return value of foreign function?
Related
I have a problem with Haskell module optimization.
There is Main module.
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.DeepSeq
import Formatting
import Formatting.Clock
import System.Clock
import Data.Array
size :: Int
size = 200 :: Int
stdMult :: (Ix a, Ix b, Ix c, Num d) =>
Array (a,b) d -> Array (b,c) d -> Array (a,c) d
stdMult x y = array resultBounds
[((i,j), sum [ x!(i,k) * y!(k,j) | k <- range (lj,uj)])
| i <- range (li,ui),
j <- range (lj',uj') ]
where ((li,lj),(ui,uj)) = bounds x
((li',lj'),(ui',uj')) = bounds y
resultBounds
| (lj,uj)==(li',ui') = ((li,lj'),(ui,uj'))
| otherwise = error "error"
main :: IO ()
main = do
let a = array ((1,1),(size, size)) [((i,j), 2*i-j) |
i <- range (1,size),
j <- range (1,size)]
let b = array ((1,1),(size, size)) [((i,j), 2*i+3*j) |
i <- range (1,size)`,
j <- range (1,size)]
start <- getTime ProcessCPUTime
let
c = stdMult a b
end <- c `deepseq` getTime ProcessCPUTime
fprint (timeSpecs % "\n") start end
return()
When stdMult in Main module, everything works ok. I replace stdMult to another module.
When I don't use ghc optimization, execution time is the same.
When I use ghc options -O3, when stdMult in Main module time execution decreases, but when stdMult in another module, execution time is almost unchanged!
For example, when stdMult in Main I have time 3 seconds, and when stdMult not in Main I have time 30 seconds, for matrix 500x500.
It is very strange!
(You need the clock and formatting packages from Hackage to compile the code.)
I can reproduce the 10x slowdown when stdMult is in a different module. Luckily a fix is easy: in the module where stdMult is defined, add an INLINABLE pragma:
{-# INLINABLE stdMult #-}
It adds the definition to the interface file (.hi) which allows inlining in the modules that uses it, which in turn allows it to be specialized to fast machine Int instead of slow abstract Ix and Num polymorphic code. (If it's in the same module GHC can inline and specialize at will, and things aren't INLINABLE by default because it can cause executable code bloat and slower compilation.)
Alternatively to INLINABLE, you can manually SPECIALIZE to the types you want optimized implementations for. This is a bit more verbose, but should be faster to compile in big projects (it will be specialized once per export, instead of once per import, at a rough guess).
{-# SPECIALIZE stdMult :: Array (Int, Int) Int -> Array (Int, Int) Int -> Array (Int, Int) Int #-}
I'm looking for a function that does what the GHCi :type command does.
Ideally, it would have a signature something like
getStaticType :: a -> String
a = getStaticType (1+2)
-- a = "(Num t) => t"
b = getStaticType zipWith
-- b = "(a -> b -> c) -> [a] -> [b] -> [c]"
(Note: this has nothing to do with Data.Dynamic. I just want the static type inferred from the compiler. In fact the function wouldn't need a runtime implementation at all, as all calls to it could be inlined as constants at compile time. I'm assuming it exists somewhere, since GHCi can do it)
You can do it like this:
import Data.Typeable
getStaticType :: Typeable a => a -> String
getStaticType = show . typeOf
Note that the type must be an instance of Typeable. You can derive Typeable automatically using the DeriveDataTypeable Haskell language extension and ... deriving (Typeable, ...).
Also note that polymorphic types cannot be identified in this way; you must always call a function with a specific type, so you can never get that polymorphic type information that you get in GHCi with compiled Haskell code.
The way GHCi does it is that it uses the GHC API to analyse an intermediary Haskell abstract syntax tree (AST) that contains type information. GHCi does not have the same restricted environment that your typical compiled Haskell program does; it can do lots of stuff to find out more information about its environment.
With TemplateHaskell, you can do it like this; first, create this module:
module TypeOf where
import Control.Monad
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
getStaticType :: Name -> Q Exp
getStaticType = lift <=< fmap pprint . reify
Then, in a different module (very important), you can do the following:
{-# LANGUAGE TemplateHaskell #-}
import TypeOf
main = putStrLn $(getStaticType 'zipWith)
This program outputs:
GHC.List.zipWith :: forall a_0 b_1 c_2 . (a_0 -> b_1 -> c_2) ->
[a_0] -> [b_1] -> [c_2]
You can use a better pretty-printer than the pprint function; take a look at the Language.Haskell.TH.Ppr module.
try http://www.haskell.org/haskellwiki/GHC/As_a_library
typed targetFile targetModule = do
defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
runGhc (Just libdir) $ do
dflags <- getSessionDynFlags
let dflags' = xopt_set dflags Opt_ImplicitPrelude
setSessionDynFlags dflags'
target <- guessTarget targetFile Nothing
setTargets [target]
load LoadAllTargets
m <- getModSummary $ mkModuleName targetModule
p <- parseModule m
t <- typecheckModule p
return $ typecheckedSource d
I'm looking for a function that does what the GHCi :type command does.
Ideally, it would have a signature something like
getStaticType :: a -> String
a = getStaticType (1+2)
-- a = "(Num t) => t"
b = getStaticType zipWith
-- b = "(a -> b -> c) -> [a] -> [b] -> [c]"
(Note: this has nothing to do with Data.Dynamic. I just want the static type inferred from the compiler. In fact the function wouldn't need a runtime implementation at all, as all calls to it could be inlined as constants at compile time. I'm assuming it exists somewhere, since GHCi can do it)
You can do it like this:
import Data.Typeable
getStaticType :: Typeable a => a -> String
getStaticType = show . typeOf
Note that the type must be an instance of Typeable. You can derive Typeable automatically using the DeriveDataTypeable Haskell language extension and ... deriving (Typeable, ...).
Also note that polymorphic types cannot be identified in this way; you must always call a function with a specific type, so you can never get that polymorphic type information that you get in GHCi with compiled Haskell code.
The way GHCi does it is that it uses the GHC API to analyse an intermediary Haskell abstract syntax tree (AST) that contains type information. GHCi does not have the same restricted environment that your typical compiled Haskell program does; it can do lots of stuff to find out more information about its environment.
With TemplateHaskell, you can do it like this; first, create this module:
module TypeOf where
import Control.Monad
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
getStaticType :: Name -> Q Exp
getStaticType = lift <=< fmap pprint . reify
Then, in a different module (very important), you can do the following:
{-# LANGUAGE TemplateHaskell #-}
import TypeOf
main = putStrLn $(getStaticType 'zipWith)
This program outputs:
GHC.List.zipWith :: forall a_0 b_1 c_2 . (a_0 -> b_1 -> c_2) ->
[a_0] -> [b_1] -> [c_2]
You can use a better pretty-printer than the pprint function; take a look at the Language.Haskell.TH.Ppr module.
try http://www.haskell.org/haskellwiki/GHC/As_a_library
typed targetFile targetModule = do
defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
runGhc (Just libdir) $ do
dflags <- getSessionDynFlags
let dflags' = xopt_set dflags Opt_ImplicitPrelude
setSessionDynFlags dflags'
target <- guessTarget targetFile Nothing
setTargets [target]
load LoadAllTargets
m <- getModSummary $ mkModuleName targetModule
p <- parseModule m
t <- typecheckModule p
return $ typecheckedSource d
I am working on this problem and had previously asked related question. Implementation of State Monad To further refine my code i tried to implement it using only one increment function.
module StateExample where
import Control.Monad.State
data GlobState = GlobState { c1 :: Int, c2:: Int, c3:: Int} deriving (Show)
newGlobState:: GlobState
newGlobState = GlobState { c1=0,c2=0,c3=0 }
incr :: String-> State GlobState ()
incr x = do
modify(\g -> g {x =x g + 1})
main:: IO()
main = do
let a1= flip execState newGlobState $ do
incr c1
incr c2
incr c1
print a
But here i am getting an error
`x' is not a (visible) constructor field name
How can i remove this error?
You have hit a weakness in Haskell: records are not first class values!
Indeed, it would be very nice to write as you have done, but it is not possible.
However, you can use different libraries to achieve the desired effect.
This is how it looks if you use
fclabels:
{-# LANGUAGE TemplateHaskell, TypeOperators #-}
module StateExample where
import Control.Monad.State hiding (modify)
import Data.Label (mkLabels)
import Data.Label.Pure ((:->))
import Data.Label.PureM
data GlobState = GlobState { _c1 :: Int , _c2 :: Int , _c3 :: Int } deriving Show
$(mkLabels [''GlobState])
newGlobState:: GlobState
newGlobState = GlobState { _c1 = 0, _c2 = 0, _c3 = 0 }
incr :: (GlobState :-> Int) -> State GlobState ()
incr x = modify x (+1)
main :: IO ()
main = do
let a = flip execState newGlobState $ do
incr c1
incr c2
incr c1
print a
There are some magic parts here. We define the GlobState with the same
record names but prependend with an underscore. Then the function
mkLabels uses TemplateHaskell to define "lenses" for every field
in the record. These lenses will have the same name but without the underscore. The argument (GlobState :-> Int) to incr is such a
lens, and we can use the modify function from Data.Label.PureM
which updates records defined this way inside the state monad. We hide
modify from Control.Monad.State, to avoid collision.
You can look at the other
functions in the
documentation for
PureM
for other functions usable with state monads, as
gets and puts.
If you do not have fclabels installed, but you have the cabal executable from the cabal-install package (which you get if you install the Haskell Platform), you can install fclabels by simply running:
cabal install fclabels
If this is the first time you run cabal, you first need to update the database:
cabal update
There is an Crypto.Random API inside the crypto-api package that specifies what it means for something to be a "pseudorandom number generator".
I have implemented this API using an instance of System.Random's RandomGen class, namely, StdGen:
instance CryptoRandomGen StdGen where
newGen bs = Right $ mkStdGen $ shift e1 24 + shift e2 16 + shift e3 8 + e4
where (e1 : e2 : e3 : e4 : _) = Prelude.map fromIntegral $ unpack bs
genSeedLength = Tagged 4
genBytes n g = Right $ genBytesHelper n empty g
where genBytesHelper 0 partial gen = (partial, gen)
genBytesHelper n partial gen = genBytesHelper (n-1) (partial `snoc` nextitem) newgen
where (nextitem, newgen) = randomR (0, 255) gen
reseed bs _ = newGen bs
However, this implementation is only for the StdGen type, but it would really work for anything in System.Random's RandomGen typeclass.
Is there a way to say that everything in RandomGen is a member of CryptoRandomGen using the given shim functions? I'd like to be able to do this in my own code, without having to change the source of either of those two libraries. My instincts would be to change the first line to something like
instance (RandomGen a) => CryptoRandomGen a where
but that doesn't appear to be syntactically correct.
Crypto-API author here. Please don't do this - it's really a violation of the implicit properties of CryptoRandomGen.
That said, here's how I'd do it: Just make a newtype that wraps your RandomGen and make that newtype an instance of CryptoRandomGen.
newtype AsCRG g = ACRG { unACRG :: g}
instance RandomGen g => CryptoRandomGen (AsCRG g) where
newGen = -- This is not possible to implement with only a 'RandomGen' constraint. Perhaps you want a 'Default' instance too?
genSeedLength = -- This is also not possible from just 'RandomGen'
genBytes nr g =
let (g1,g2) = split g
randInts :: [Word32]
randInts = B.concat . map Data.Serialize.encode
. take ((nr + 3) `div` 4)
$ (randoms g1 :: [Word32])
in (B.take nr randInts, g2)
reseed _ _ = -- not possible w/o more constraints
newGenIO = -- not possible w/o more constraints
So you see, you can split the generator (or manage many intermediate generators), make the right number of Ints (or in my case, Word32s), encode them, and return the bytes.
Because RandomGen is limited to just generation (and splitting), there isn't any straight-forward way to support instatiation, reinstantiation, or querying properties such as the seed length.
As far as I know, this is impossible, unless you're willing to turn on UndecidableInstances (which, of course, can make the typechecker go in an infinite loop). Here's an example that makes every instance of Monad an instance of Functor:
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
module Main
where
import Control.Monad (liftM)
instance (Monad a) => Functor a where
fmap = liftM
-- Test code
data MyState a = MyState { unM :: a }
deriving Show
instance Monad MyState where
return a = MyState a
(>>=) m k = k (unM m)
main :: IO ()
main = print . fmap (+ 1) . MyState $ 1
Testing:
*Main> :main
MyState { unM = 2 }
In your case, this translates to:
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
instance (RandomGen a) => CryptoRandomGen a where
newGen = ...
genSeedLength = ...
genBytes = ...
reseed = ...
As an aside, I once asked how to implement this without UndecidableInstances on haskell-cafe and got this answer (the same workaround that Thomas proposed; I consider it ugly).