diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 50c4f7ef..97e726fa 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -31,8 +31,9 @@ jobs: - { os: ubuntu-latest, ghc: "9.0.2" } - { os: ubuntu-latest, ghc: "9.2.8" } - { os: ubuntu-latest, ghc: "9.4.8" } - - { os: ubuntu-latest, ghc: "9.6.4" } - - { os: ubuntu-latest, ghc: "9.8.1" } + - { os: ubuntu-latest, ghc: "9.6.6" } + - { os: ubuntu-latest, ghc: "9.8.2" } + - { os: ubuntu-latest, ghc: "9.10.1" } # MacOS - { os: macOS-latest, ghc: "8.0.2" } - { os: macOS-latest, ghc: "8.2.2" } @@ -43,8 +44,9 @@ jobs: - { os: macOS-latest, ghc: "9.0.2" } - { os: macOS-latest, ghc: "9.2.8" } - { os: macOS-latest, ghc: "9.4.8" } - - { os: macOS-latest, ghc: "9.6.4" } - - { os: macOS-latest, ghc: "9.8.1" } + - { os: macOS-latest, ghc: "9.6.6" } + - { os: macOS-latest, ghc: "9.8.2" } + - { os: macOS-latest, ghc: "9.10.1" } # Windows - { os: windows-latest, ghc: "8.0.2" } - { os: windows-latest, ghc: "8.2.2" } @@ -55,10 +57,11 @@ jobs: - { os: windows-latest, ghc: "9.0.2" } - { os: windows-latest, ghc: "9.2.8" } - { os: windows-latest, ghc: "9.4.8" } - - { os: windows-latest, ghc: "9.6.4" } - - { os: windows-latest, ghc: "9.8.1" } + - { os: windows-latest, ghc: "9.6.6" } + - { os: windows-latest, ghc: "9.8.2" } + - { os: windows-latest, ghc: "9.10.1" } steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: haskell-actions/setup@v2 id: setup-haskell-cabal @@ -69,7 +72,7 @@ jobs: - name: Update cabal package database run: cabal update - - uses: actions/cache@v3 + - uses: actions/cache@v4 name: Cache cabal stuff with: path: | @@ -85,6 +88,12 @@ jobs: echo $EXTRA_FLAGS cabal $EXTRA_FLAGS configure --haddock-all --enable-tests --enable-benchmarks --benchmark-option=-l cabal $EXTRA_FLAGS build all --write-ghc-environment-files=always + + - name: Doctest + run: | + cabal install doctest --ignore-project --overwrite-policy=always + cabal repl --build-depends=unliftio --with-compiler=doctest --repl-options='-w -Wdefault' + build-stack: name: CI-stack runs-on: ${{ matrix.os }} @@ -119,26 +128,46 @@ jobs: ghc: '9.4.8' stack-yaml: stack.yaml - resolver: lts-22 - ghc: '9.6.4' + ghc: '9.6.6' stack-yaml: stack.yaml - resolver: nightly stack-yaml: stack.yaml - # Latest stable for MacOS: ghc-8.8.4 - - resolver: lts-16 - os: macos-latest - ghc: '8.8.4' - stack-yaml: stack-old.yaml - # Latest stable for Windows: ghc-8.6.4 + # MacOS-latest + - resolver: lts-20 + os: macos-13 + ghc: '9.2.8' + stack-yaml: stack.yaml + - resolver: lts-21 + os: macos-13 + ghc: '9.4.8' + stack-yaml: stack.yaml + - resolver: lts-22 + os: macos-13 + ghc: '9.6.6' + stack-yaml: stack.yaml + # Windows-latest - resolver: lts-14 os: windows-latest ghc: '8.6.5' stack-yaml: stack-old.yaml + - resolver: lts-20 + os: windows-latest + ghc: '9.2.8' + stack-yaml: stack.yaml + - resolver: lts-21 + os: windows-latest + ghc: '9.4.8' + stack-yaml: stack.yaml + - resolver: lts-22 + os: windows-latest + ghc: '9.6.6' + stack-yaml: stack.yaml env: STACK_YAML: '${{ matrix.stack-yaml }}' STACK_ARGS: '--resolver ${{ matrix.resolver }} --system-ghc' cache-version: v5 # bump up this version to invalidate currently stored cache steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: haskell-actions/setup@v2 id: setup-haskell-stack @@ -146,12 +175,11 @@ jobs: with: ghc-version: ${{ matrix.ghc }} enable-stack: true - stack-version: 'latest' - cabal-version: '3.10' + stack-version: ${{ matrix.resolver == 'lts-11' && '2.15.5' || 'latest' }} - name: Cache id: cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.stack @@ -160,18 +188,9 @@ jobs: restore-keys: | ${{ runner.os }}-${{ matrix.resolver }}-${{ env.cache-version }} - # Executable files somehow become incompatible after restoring on MacOS from a - # previous build, so it needs to be cleaned up. This is very inconvenient and will - # need to be fixed. - - name: MacOS workaround for failure due to setup-exe-cache - if: steps.cache.outputs.cache-hit == 'true' && matrix.os == 'macos-latest' - run: | - rm -r ~/.stack/setup-exe-cache - rm -r .stack-work - - name: Windows Cache id: cache-windows - uses: actions/cache@v3 + uses: actions/cache@v4 if: matrix.os == 'windows-latest' with: path: | @@ -243,7 +262,7 @@ jobs: args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +" - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - if: matrix.arch == 'arm32v7' uses: docker://hasufell/arm32v7-ubuntu-haskell:focal @@ -265,8 +284,8 @@ jobs: s390x: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: uraimo/run-on-arch-action@v2.5.0 + - uses: actions/checkout@v4 + - uses: uraimo/run-on-arch-action@v2.8.1 timeout-minutes: 60 with: arch: s390x diff --git a/.github/workflows/doctest.yml b/.github/workflows/doctest.yml deleted file mode 100644 index 9bb22c7e..00000000 --- a/.github/workflows/doctest.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: doctest - -on: - pull_request: - branches: - - master - -jobs: - doctest: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - run: cabal update - - # NOTE: We can't use `cabal doctest` here, as `cabal doctest` uses - # `--build-depends=QuickCheck`, which results in a dependency cycle. - - run: cabal install doctest --ignore-project --overwrite-policy=always && cabal build && cabal repl --build-depends=unliftio --with-compiler=doctest --repl-options='-w -Wdefault' diff --git a/CHANGELOG.md b/CHANGELOG.md index 122ed4ce..bf876a2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # 1.3.0 +* Add `Uniform` instance for `Maybe` and `Either` * Add `SplitGen` and `splitGen` * Add `shuffleList` and `shuffleListM`: [#140](https://github.com/haskell/random/pull/140) * Add `mkStdGen64`: [#155](https://github.com/haskell/random/pull/155) diff --git a/random.cabal b/random.cabal index 0d635a37..8e238dc3 100644 --- a/random.cabal +++ b/random.cabal @@ -72,8 +72,9 @@ tested-with: GHC == 8.0.2 , GHC == 9.0.2 , GHC == 9.2.8 , GHC == 9.4.8 - , GHC == 9.6.4 - , GHC == 9.8.1 + , GHC == 9.6.6 + , GHC == 9.8.2 + , GHC == 9.10.1 source-repository head type: git @@ -160,6 +161,8 @@ test-suite spec-inspection random, tasty >=1.0 && <1.6, tasty-inspection-testing + if impl(ghc >=9.10) + buildable: False benchmark legacy-bench type: exitcode-stdio-1.0 diff --git a/src/System/Random.hs b/src/System/Random.hs index 800bb7ea..1e2e497c 100644 --- a/src/System/Random.hs +++ b/src/System/Random.hs @@ -340,11 +340,11 @@ class Random a where -- closed interval /[lo,hi]/, together with a new generator. It is unspecified -- what happens if /lo>hi/, but usually the values will simply get swapped. -- - -- >>> let gen = mkStdGen 2021 + -- >>> let gen = mkStdGen 26 -- >>> fst $ randomR ('a', 'z') gen - -- 't' - -- >>> fst $ randomR ('z', 'a') gen - -- 't' + -- 'z' + -- >>> fst $ randomR ('a', 'z') gen + -- 'z' -- -- For continuous types there is no requirement that the values /lo/ and /hi/ are ever -- produced, but they may be, depending on the implementation and the interval. @@ -353,8 +353,8 @@ class Random a where -- defined on per type basis. For example product types will treat their values -- independently: -- - -- >>> fst $ randomR (('a', 5.0), ('z', 10.0)) $ mkStdGen 2021 - -- ('t',6.240232662366564) + -- >>> fst $ randomR (('a', 5.0), ('z', 10.0)) $ mkStdGen 26 + -- ('z',7.27305019146949) -- -- In case when a lawful range is desired `uniformR` should be used -- instead. diff --git a/src/System/Random/Internal.hs b/src/System/Random/Internal.hs index a193f438..f6bba9e2 100644 --- a/src/System/Random/Internal.hs +++ b/src/System/Random/Internal.hs @@ -109,7 +109,7 @@ import GHC.ST (ST(..)) import GHC.Word import Numeric.Natural (Natural) import System.IO.Unsafe (unsafePerformIO) -import System.Random.GFinite (Cardinality(..), GFinite(..)) +import System.Random.GFinite (Cardinality(..), GFinite(..), Finite) import qualified System.Random.SplitMix as SM import qualified System.Random.SplitMix32 as SM32 import Data.Kind @@ -1474,6 +1474,10 @@ instance UniformRange Bool where {-# INLINE uniformRM #-} isInRange = isInRangeOrd +instance (Finite a, Uniform a) => Uniform (Maybe a) + +instance (Finite a, Uniform a, Finite b, Uniform b) => Uniform (Either a b) + -- | See [Floating point number caveats](System-Random-Stateful.html#fpcaveats). instance UniformRange Double where uniformRM (l, h) g diff --git a/src/System/Random/Stateful.hs b/src/System/Random/Stateful.hs index 8d0b3bd9..532ef7ea 100644 --- a/src/System/Random/Stateful.hs +++ b/src/System/Random/Stateful.hs @@ -299,16 +299,16 @@ withMutableGen_ fg action = thawGen fg >>= action -- ====__Examples__ -- -- >>> import System.Random.Stateful --- >>> let pureGen = mkStdGen 137 +-- >>> let pureGen = mkStdGen 139 -- >>> g <- newIOGenM pureGen -- >>> randomM g :: IO Double --- 0.5728354935654512 +-- 0.33775117339631733 -- -- You can use type applications to disambiguate the type of the generated numbers: -- -- >>> :seti -XTypeApplications -- >>> randomM @Double g --- 0.6268211351114488 +-- 0.9156875994165681 -- -- @since 1.2.0 randomM :: forall a g m. (Random a, RandomGen g, FrozenGen g m) => MutableGen g m -> m a