bluefin-random (empty) → 0.0.16.0
raw patch · 4 files changed
+303/−0 lines, 4 filesdep +basedep +bluefindep +random
Dependencies added: base, bluefin, random
Files
- CHANGELOG.md +3/−0
- LICENSE +20/−0
- bluefin-random.cabal +84/−0
- src/Bluefin/Random.hs +196/−0
+ CHANGELOG.md view
@@ -0,0 +1,3 @@+# 0.0.16.0++* Initial version
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2024 Tom Ellis++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ bluefin-random.cabal view
@@ -0,0 +1,84 @@+cabal-version: 3.0+name: bluefin-random+version: 0.0.16.0+license: MIT+license-file: LICENSE+author: Tom Ellis+maintainer: Tom Ellis+build-type: Simple+extra-doc-files: CHANGELOG.md+description: The Bluefin effect system, random generators+synopsis: The Bluefin effect system, random generators+homepage: https://github.com/tomjaguarpaw/bluefin+bug-reports: https://github.com/tomjaguarpaw/bluefin/issues++common defaults+ ghc-options: -Wall+ default-extensions:+ -- GHC2021+ BangPatterns+ BinaryLiterals+ ConstrainedClassMethods+ ConstraintKinds+ DeriveDataTypeable+ DeriveFoldable+ DeriveFunctor+ DeriveGeneric+ DeriveLift+ DeriveTraversable+ DoAndIfThenElse+ EmptyCase+ EmptyDataDecls+ EmptyDataDeriving+ ExistentialQuantification+ ExplicitForAll+ -- Not available until 9.2+ -- FieldSelectors+ FlexibleContexts+ FlexibleInstances+ ForeignFunctionInterface+ GADTSyntax+ GeneralisedNewtypeDeriving+ HexFloatLiterals+ ImplicitPrelude+ -- Not available until 8.10+ -- ImportQualifiedPost+ InstanceSigs+ KindSignatures+ MonomorphismRestriction+ MultiParamTypeClasses+ NamedFieldPuns+ NamedWildCards+ NumericUnderscores+ PatternGuards+ PolyKinds+ PostfixOperators+ RankNTypes+ RelaxedPolyRec+ ScopedTypeVariables+ StandaloneDeriving+ -- Not available in 8.6+ -- StandaloneKindSignatures+ StarIsType+ TraditionalRecordSyntax+ TupleSections+ TypeApplications+ TypeOperators+ TypeSynonymInstances+ NoExplicitNamespaces+ -- Others+ DataKinds+ DerivingStrategies+ GADTs+ LambdaCase++library+ import: defaults+ default-language: Haskell2010+ hs-source-dirs: src+ build-depends:+ base >= 4.12 && < 4.22,+ random >= 1.3 && < 1.4,+ bluefin >= 0.0.16.0 && < 0.1+ exposed-modules:+ Bluefin.Random
+ src/Bluefin/Random.hs view
@@ -0,0 +1,196 @@+{-# LANGUAGE TypeFamilies #-}++module Bluefin.Random+ ( -- * Handle+ Random,++ -- * Handlers+ withInitStdGen,++ -- ** Special purpose handlers+ -- $specialpurposehandlers+ evalRandom,+ runRandom,++ -- * Effectful operations+ -- $effectfuloperations++ -- * Internal details+ -- $internaldetails+ RandomPure,+ )+where++import Bluefin.Compound (Handle)+import Bluefin.Eff (Eff, Effects, (:&), (:>))+import Bluefin.IO (IOE, effIO)+import Bluefin.State (State, get, put, runState)+import qualified System.Random as Rnd+import qualified System.Random.Stateful as Rnd++-- $specialpurposehandlers+--+-- In the vast majority of cases you should use 'withInitStdGen' and+-- you won't have any need for these special purpose handlers.++-- $effectfuloperations+--+-- To run random operations in Bluefin you should use the random+-- operations in the "System.Random.Stateful" module from the @random@+-- package. Here are their type signatures when restricted to+-- Bluefin's @Random@:+--+-- @+-- 'System.Random.Stateful.uniformM' ::+-- (Uniform a, RandomGen g, e1 :> es) =>+-- Random g e1 ->+-- Eff es a+-- @+--+-- @+-- 'System.Random.Stateful.uniformRM' ::+-- (UniformRange a, RandomGen g, e1 :> es) =>+-- (a, a) ->+-- Random g e1 ->+-- Eff es a+-- @+--+-- @+-- 'System.Random.Stateful.uniformListM' ::+-- (Uniform a, RandomGen g, e1 :> es) =>+-- Int ->+-- Random g e1 ->+-- Eff es [a]+-- @+--+-- @+-- 'System.Random.Stateful.uniformListRM' ::+-- (UniformRange a, RandomGen g, e1 :> es) =>+-- Int ->+-- (a, a) ->+-- Random g e1 ->+-- Eff es [a]+-- @+--+-- @+-- 'System.Random.Stateful.uniformShuffleListM' ::+-- (RandomGen g, e1 :> es) =>+-- [a] ->+-- Random g e1 ->+-- Eff es [a]+-- @+--+-- @+-- 'System.Random.Stateful.uniformByteArrayM' ::+-- (RandomGen g, e1 :> es) =>+-- Bool ->+-- Int ->+-- Random g e1 ->+-- Eff es ByteArray+-- @+--+-- @+-- 'System.Random.Stateful.uniformByteStringM' ::+-- (RandomGen g, e1 :> es) =>+-- Int ->+-- Random g e1 ->+-- Eff es ByteString+-- @+--+-- @+-- 'System.Random.Stateful.uniformShortByteStringM' ::+-- (RandomGen g, e1 :> es) =>+-- Int ->+-- Random g e1 ->+-- Eff es ShortByteString+-- @+--+-- @+-- 'System.Random.Stateful.uniformDouble01M' ::+-- (RandomGen g, e1 :> es) =>+-- Random g e1 ->+-- Eff es Double+-- @+--+-- @+-- 'System.Random.Stateful.uniformDoublePositive01M' ::+-- (RandomGen g, e1 :> es) =>+-- Random g e1 ->+-- Eff es Double+-- @+--+-- @+-- 'System.Random.Stateful.uniformFloat01M' ::+-- (RandomGen g, e1 :> es) =>+-- Random g e1 ->+-- Eff es Float+-- @+--+-- @+-- 'System.Random.Stateful.uniformFloatPositive01M' ::+-- (RandomGen g, e1 :> es) =>+-- Random g e1 ->+-- Eff es Float+-- @++-- $internaldetails+--+-- 'RandomPure' is an internal detail that is used to implement a+-- 'System.Random.Stateful.FrozenGen' instance for 'Random'. You may+-- see it in error messages, so we include it here from completeness.+-- You will most likely never need to use @RandomPure@ directly.++newtype Random g e = Random (State g e)+ deriving newtype (Handle)++newtype RandomPure g (e :: Effects) = RandomPure g+ deriving newtype (Rnd.RandomGen)++instance+ (e :> es, Rnd.RandomGen g) =>+ Rnd.StatefulGen (Random g e) (Eff es)+ where+ uniformWord64 =+ flip Rnd.modifyGen Rnd.genWord64++ uniformByteArrayM pinned size =+ flip Rnd.modifyGen (Rnd.uniformByteArray pinned size)++instance+ (e :> es, Rnd.RandomGen g) =>+ Rnd.FrozenGen (RandomPure g e) (Eff es)+ where+ type MutableGen (RandomPure g e) (Eff es) = Random g e++ modifyGen (Random s) f = do+ (a, RandomPure g) <- f . RandomPure <$> get s+ put s g+ pure a++runRandom ::+ g ->+ (forall e. Random g e -> Eff (e :& es) a) ->+ -- | ͘+ Eff es (a, g)+runRandom g f = runState g (f . Random)++evalRandom ::+ g ->+ (forall e. Random g e -> Eff (e :& es) a) ->+ -- | ͘+ Eff es a+evalRandom g f = fst <$> runRandom g f++-- | The simplest way to handle a Bluefin 'Random' effect. This is+-- the handler you should use unless you know you have a particular+-- need to use a @Rnd.RandomGen@ other than @Rnd.StdGen@ or you know+-- you need to create a @Rnd.StdGen@ seed in a non-standard way.+withInitStdGen ::+ (e1 :> es) =>+ IOE e1 ->+ (forall e. Random Rnd.StdGen e -> Eff (e :& es) a) ->+ -- | ͘+ Eff es a+withInitStdGen io k = do+ g <- effIO io Rnd.initStdGen+ evalRandom g k