Skip to content

Commit 630af74

Browse files
committed
io-classes: Add MonadUnique to support Data.Unique
1 parent 4f5a4cd commit 630af74

File tree

4 files changed

+95
-0
lines changed

4 files changed

+95
-0
lines changed

io-classes/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Revsion history of io-classes
22

3+
### next release
4+
5+
* Added module `Control.Monad.Class.MonadUnique` generalising `Data.Unique`.
6+
* mtl: Added module `Control.Monad.Class.MonadUnique.Trans` providing monad transformer instances for `MonadUnique`.
7+
38
### 1.8.0.1
49

510
* Added support for `ghc-9.2`.

io-classes/io-classes.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ library
8787
Control.Monad.Class.MonadTime
8888
Control.Monad.Class.MonadTimer
8989
Control.Monad.Class.MonadTest
90+
Control.Monad.Class.MonadUnique
9091
default-language: GHC2021
9192
default-extensions: LambdaCase
9293
build-depends: base >=4.16 && <4.22,
@@ -174,6 +175,7 @@ library mtl
174175
, Control.Monad.Class.MonadTime.SI.Trans
175176
, Control.Monad.Class.MonadTimer.Trans
176177
, Control.Monad.Class.MonadTimer.SI.Trans
178+
, Control.Monad.Class.MonadUnique.Trans
177179
build-depends: base,
178180
array,
179181
mtl,
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{-# OPTIONS_GHC -Wno-orphans #-}
2+
{-# LANGUAGE TypeFamilies #-}
3+
4+
module Control.Monad.Class.MonadUnique.Trans () where
5+
6+
import Control.Monad.Cont (ContT)
7+
import Control.Monad.Except (ExceptT)
8+
import Control.Monad.RWS.Lazy qualified as Lazy
9+
import Control.Monad.RWS.Strict qualified as Strict
10+
import Control.Monad.State.Lazy qualified as Lazy
11+
import Control.Monad.State.Strict qualified as Strict
12+
import Control.Monad.Writer.Lazy qualified as Lazy
13+
import Control.Monad.Writer.Strict qualified as Strict
14+
15+
import Control.Monad.Class.MonadUnique
16+
17+
18+
instance MonadUnique m => MonadUnique (ContT r m) where
19+
type Unique (ContT r m) = UniqueFor (ContT r) m
20+
21+
instance MonadUnique m => MonadUnique (ExceptT e m) where
22+
type Unique (ExceptT e m) = UniqueFor (ExceptT e) m
23+
24+
instance (MonadUnique m, Monoid w) => MonadUnique (Lazy.RWST r w s m) where
25+
type Unique (Lazy.RWST r w s m) = UniqueFor (Lazy.RWST r w s) m
26+
27+
instance (MonadUnique m, Monoid w) => MonadUnique (Strict.RWST r w s m) where
28+
type Unique (Strict.RWST r w s m) = UniqueFor (Strict.RWST r w s) m
29+
30+
instance MonadUnique m => MonadUnique (Lazy.StateT s m) where
31+
type Unique (Lazy.StateT s m) = UniqueFor (Lazy.StateT s) m
32+
33+
instance MonadUnique m => MonadUnique (Strict.StateT s m) where
34+
type Unique (Strict.StateT s m) = UniqueFor (Strict.StateT s) m
35+
36+
instance (MonadUnique m, Monoid w) => MonadUnique (Lazy.WriterT w m) where
37+
type Unique (Lazy.WriterT w m) = UniqueFor (Lazy.WriterT w) m
38+
39+
instance (MonadUnique m, Monoid w) => MonadUnique (Strict.WriterT w m) where
40+
type Unique (Strict.WriterT w m) = UniqueFor (Strict.WriterT w) m
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{-# LANGUAGE DefaultSignatures #-}
2+
{-# LANGUAGE TypeFamilyDependencies #-}
3+
4+
-- | A generalisation of the
5+
-- <https://hackage.haskell.org/package/base/docs/Data-Unique.html Data.Unique>
6+
-- API to both 'IO' and <https://hackage.haskell.org/package/io-sim IOSim>.
7+
--
8+
module Control.Monad.Class.MonadUnique (
9+
MonadUnique (..),
10+
UniqueFor (..),
11+
) where
12+
13+
-- base
14+
import Data.Kind (Type)
15+
import Data.Unique qualified as IO
16+
17+
-- transformers
18+
import Control.Monad.Reader (MonadTrans(..), ReaderT(..), lift)
19+
20+
21+
class (Monad m, Eq (Unique m), Ord (Unique m)) => MonadUnique m where
22+
type Unique m = (unique :: Type) | unique -> m
23+
newUnique :: m (Unique m)
24+
hashUnique :: Unique m -> Int
25+
26+
default
27+
newUnique
28+
:: (m ~ t n, Unique m ~ UniqueFor t n, MonadTrans t, MonadUnique n)
29+
=> m (Unique m)
30+
default
31+
hashUnique
32+
:: (m ~ t n, Unique m ~ UniqueFor t n, MonadUnique n)
33+
=> Unique m -> Int
34+
newUnique = lift (MkUniqueFor <$> newUnique)
35+
hashUnique = hashUnique . unMkUniqueFor
36+
37+
instance MonadUnique IO where
38+
type Unique IO = IO.Unique
39+
newUnique = IO.newUnique
40+
hashUnique = IO.hashUnique
41+
42+
43+
newtype UniqueFor t m = MkUniqueFor{ unMkUniqueFor :: Unique m }
44+
deriving instance MonadUnique m => Eq (UniqueFor r m)
45+
deriving instance MonadUnique m => Ord (UniqueFor r m)
46+
47+
instance MonadUnique m => MonadUnique (ReaderT r m) where
48+
type Unique (ReaderT r m) = UniqueFor (ReaderT r) m

0 commit comments

Comments
 (0)