Skip to content

Help/advice upgrading MonadRandom to 1.3.0? #179

Closed
@byorgey

Description

@byorgey

Trying to build the MonadRandom package with random-1.3 fails with the following compilation error (see byorgey/MonadRandom#54):

Control/Monad/Trans/Random/Strict.hs:285:10: error: [GHC-18872]
    • Couldn't match type: MutableGen f0 (RandT g m)
                     with: RandGen g
        arising from a use of ‘System.Random.Internal.$dmuniformByteArrayM’
      The type variable ‘f0’ is ambiguous
    • In the expression:
        System.Random.Internal.$dmuniformByteArrayM
          @(RandGen g) @(RandT g m)
      In an equation for ‘uniformByteArrayM’:
          uniformByteArrayM
            = System.Random.Internal.$dmuniformByteArrayM
                @(RandGen g) @(RandT g m)
      In the instance declaration for
        ‘StatefulGen (RandGen g) (RandT g m)’
    • Relevant bindings include
        uniformByteArrayM :: Bool
                             -> Int -> RandGen g -> RandT g m Data.Array.Byte.ByteArray
          (bound at Control/Monad/Trans/Random/Strict.hs:285:10)
    |
285 | instance (Monad m, RandomGen g) => StatefulGen (RandGen g) (RandT g m) where

It seems this is a type error in some generic auto-generated code for uniformByteArrayM, which was added to the StatefulGen class in 1.3. Looking at the default type signature for uniformByteArrayM (here: https://hackage.haskell.org/package/random-1.3.0/docs/src/System.Random.Internal.html#uniformByteArrayM), we see this:

  default uniformByteArrayM ::
    (RandomGen f, FrozenGen f m, g ~ MutableGen f m) => Bool -> Int -> g -> m ByteArray
  uniformByteArrayM isPinned n g = modifyGen g (uniformByteArray isPinned n)

I think I see how this is supposed to work: MutableGen has a functional dependency from its output to its first parameter, so g ~ MutableGen f m should be enough to fix f. The problem is really that we don't have a FrozenGen g (RandT g m) instance. After carrying out a bunch of type substitutions, I am pretty sure the instance I want looks something like this:

instance FrozenGen g (RandT g m) where
  type MutableGen g (RandT g m) = RandGen g
  freezeGen = _
  overwriteGen = _

However, this fails because it overlaps with an instance in System.Random.Internal!

Control/Monad/Trans/Random/Strict.hs:293:8: error: [GHC-34447]
    Conflicting family instance declarations:
      MutableGen g (RandT g m) = RandGen g
        -- Defined at Control/Monad/Trans/Random/Strict.hs:293:8
      MutableGen (StateGen g) m = StateGenM g
        -- Defined in module System.Random.Internal
    |
293 |   type MutableGen g (RandT g m) = RandGen g

So now I am at a bit of a loss how to proceed. Any advice, pointing out something I am doing wrong, etc. would be very welcome!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions