Declare all instances of a typeclass are in another typeclass without modifying the original class declarations

后端 未结 2 768
日久生厌
日久生厌 2021-01-23 08:39

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

2条回答
  •  庸人自扰
    2021-01-23 08:55

    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).

提交回复
热议问题