packages feed

random-effin (empty) → 0.1.0.0

raw patch · 4 files changed

+208/−0 lines, 4 filesdep +MonadRandomdep +basedep +effinsetup-changed

Dependencies added: MonadRandom, base, effin, random

Files

+ Control/Effect/Random.hs view
@@ -0,0 +1,135 @@+{-# LANGUAGE CPP, DataKinds, DeriveDataTypeable, DeriveFunctor              #-}+{-# LANGUAGE ExistentialQuantification, FlexibleContexts, FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses, NoMonomorphismRestriction               #-}+{-# LANGUAGE ScopedTypeVariables, StandaloneDeriving, TupleSections         #-}+{-# LANGUAGE TypeFamilies, TypeOperators, UndecidableInstances              #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+module Control.Effect.Random+       (module System.Random,+        Rand,+        -- * Execution+        runRand, evalRand, evalRandIO,+        -- * Generator functions+        getRandom, getRandomR, getRandoms, getRandomRs,+        fromList, uniform,+        -- * Misc+        withSplit+        ) where+import Control.Arrow  (first)+import Control.Effect (Effect, EffectLift, Is, MemberEffect, Row (..))+import Control.Effect (eliminate, intercept, lift, send)+import Control.Monad  (liftM)+import Data.Data      (Typeable)+import System.Random  (Random (..), RandomGen (..), StdGen, newStdGen)+#ifdef MONADRANDOM+import qualified Control.Monad.Random.Class as C+#endif++-- | Random number generator+--+-- Since 0.1.0.0+data Rand g a = RandomGen g => Rand (g -> (a, g))+              deriving (Typeable)++instance Functor (Rand g) where+  fmap g (Rand f) = Rand (first g . f)++type instance Is Rand f = IsRand f+++type family IsRand f where+  IsRand (Rand g) = True+  IsRand f        = False++class (RandomGen g, MemberEffect Rand (Rand g) l) => EffectRandom g l+instance (RandomGen g, MemberEffect Rand (Rand g) l) => EffectRandom g l++#ifdef MONADRANDOM+instance EffectRandom g l => C.MonadRandom (Effect l) where+  getRandom   = getRandom+  getRandoms  = getRandoms+  getRandomR  = getRandomR+  getRandomRs = getRandomRs+#endif++-- | Return a randomly-selected value of type a. See 'random' for details.+--+-- Since 0.1.0.0+getRandom :: forall a g l . (Random a, EffectRandom g l) => Effect l a+getRandom = send $ Rand (random :: g -> (a, g))++-- | Return an infinite stream of random values of type a. See 'randoms' for details.+--+-- Since 0.1.0.0+getRandoms :: forall a g l. (Random a, EffectRandom g l) => Effect l [a]+getRandoms = send $ Rand $ \(g :: g) ->+  first randoms $ split g++-- | Return a randomly-selected value of type a in the range @(lo,hi)@. See 'randomR' for details.+--+-- Since 0.1.0.0+getRandomR :: forall a g l. (Random a, EffectRandom g l) => (a, a) -> Effect l a+getRandomR bd = send $ Rand $ \ (g :: g) -> randomR bd g++-- | Return an infinite stream of randomly-selected value+-- of type @a@ in the range @(lo,hi)@. See 'randomRs' for details.+--+-- Since 0.1.0.0+getRandomRs :: forall a g l. (Random a, EffectRandom g l) => (a, a) -> Effect l [a]+getRandomRs bd = send $  Rand $ \(g :: g) -> let (g', g'') = split g in (randomRs bd g', g'')++-- | Sample a random value from a weighted list. The total weight of all elements must not be 0.+--+-- Since 0.1.0.0+fromList :: EffectRandom g l => [(a, Rational)] -> Effect l a+fromList [] = error "Effect.Random.fromList called with empty list"+fromList [(x, _)] = return x+fromList xs = do+  let s  = fromRational $ sum $ map snd xs :: Double+      cs = scanl1 (\(_,q) (y,s') -> (y, s'+q)) xs+  p <- liftM toRational (getRandomR (0.0,s))+  return . fst . head $ dropWhile (\(_,q) -> q < p) cs++-- | Sample a value from a uniform distribution of a list of elements.+--+-- Since 0.1.0.0+uniform :: (EffectRandom g l) => [a] -> Effect l a+uniform xs = fromList $ map (flip (,) 1) xs++-- | Run a computation with random numbers+--+-- Since 0.1.0.0+runRand :: forall a l g. RandomGen g+        => g                         -- ^ initial internal random generator+        -> Effect (Rand g :+ l) a    -- ^ Effectect using random numbers+        -> Effect l (a, g)+runRand g0 act = eliminate ret handle act g0+  where+    ret a g = return (a, g)+    handle :: Rand g (g -> Effect l (a, g)) -> g -> Effect l (a, g)+    handle (Rand tog) g = do+      let (cont, g') = tog g+      cont g'++-- | Run a computation with random numbers, discarding the final generator.+--+-- Since 0.1.0.0+evalRand :: RandomGen g => g -> Effect (Rand g :+ l) a -> Effect l a+evalRand g = liftM fst . runRand g++-- | Run a computation with random numbers, discarding the final generator.+--+-- Since 0.1.0.0+evalRandIO :: EffectLift IO l => Effect (Rand StdGen :+ l) a -> Effect l a+evalRandIO eff = do+  g <- lift newStdGen+  evalRand g eff++-- | Split the current generator and execute the given computation with it.+--+-- Since 0.1.0.0+withSplit :: forall g l a. EffectRandom g l => Effect l a -> Effect l a+withSplit eff = do+  g <- send $ Rand split+  let run (Rand fromg) = fst $ fromg (g :: g)+  intercept return run eff
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, Hiromi ISHII++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Hiromi ISHII nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ random-effin.cabal view
@@ -0,0 +1,41 @@+-- Initial random-eff.cabal generated by cabal init.  For further +-- documentation, see http://haskell.org/cabal/users-guide/++name:                random-effin+version:             0.1.0.0+synopsis:            A simple random generator library for effin+description:         A simple random generator library for effin+license:             BSD3+license-file:        LICENSE+author:              Hiromi ISHII+maintainer:          konn.jinro_at_gmail.com+copyright:           2014 (c) Hiromi ISHII+category:            Control, Effect+build-type:          Simple+-- extra-source-files:  examples/*.hs+cabal-version:       >=1.10++source-repository head+  type: git+  location: git://github.com/konn/random-effin.git++flag MonadRandom+  description: Enable MonadRandom instances+  default:     False++library+  if flag(MonadRandom)+    build-depends:     MonadRandom >= 0.3 && < 0.4+    cpp-options:       -DMONADRANDOM+  exposed-modules:     Control.Effect.Random+  other-extensions:    DeriveDataTypeable,+                       DeriveFunctor,+                       ExistentialQuantification,+                       FlexibleContexts,+                       MultiParamTypeClasses,+                       NoMonomorphismRestriction,+                       ScopedTypeVariables+  build-depends:       base               >=4   && <5+               ,       effin              >=0.2 && <0.3+               ,       random             >=1.0 && <1.1+  default-language:    Haskell2010