2019-03-11 16:04:15 +01:00
|
|
|
{-# LANGUAGE AllowAmbiguousTypes #-}
|
|
|
|
{-# LANGUAGE ConstraintKinds #-}
|
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
|
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
|
|
|
|
|
|
{-# OPTIONS_GHC -Wno-orphans #-}
|
|
|
|
|
|
|
|
module Nix.Var where
|
|
|
|
|
2019-03-17 22:47:38 +01:00
|
|
|
import Control.Monad.Ref
|
|
|
|
import Data.GADT.Compare
|
|
|
|
import Data.IORef
|
|
|
|
import Data.Maybe
|
|
|
|
import Data.STRef
|
2020-05-25 19:28:26 +02:00
|
|
|
import Type.Reflection ((:~:)(Refl))
|
2019-03-11 16:04:15 +01:00
|
|
|
|
2019-03-17 22:47:38 +01:00
|
|
|
import Unsafe.Coerce
|
2019-03-11 16:04:15 +01:00
|
|
|
|
|
|
|
type Var m = Ref m
|
|
|
|
|
2019-03-17 00:23:40 +01:00
|
|
|
type MonadVar m = MonadAtomicRef m
|
2019-03-11 16:04:15 +01:00
|
|
|
|
2019-03-17 22:47:38 +01:00
|
|
|
eqVar :: forall m a . GEq (Ref m) => Ref m a -> Ref m a -> Bool
|
2019-03-11 16:04:15 +01:00
|
|
|
eqVar a b = isJust $ geq a b
|
|
|
|
|
|
|
|
newVar :: MonadRef m => a -> m (Ref m a)
|
|
|
|
newVar = newRef
|
|
|
|
|
|
|
|
readVar :: MonadRef m => Ref m a -> m a
|
|
|
|
readVar = readRef
|
|
|
|
|
|
|
|
writeVar :: MonadRef m => Ref m a -> a -> m ()
|
|
|
|
writeVar = writeRef
|
|
|
|
|
|
|
|
atomicModifyVar :: MonadAtomicRef m => Ref m a -> (a -> (a, b)) -> m b
|
|
|
|
atomicModifyVar = atomicModifyRef
|
|
|
|
|
|
|
|
--TODO: Upstream GEq instances
|
|
|
|
instance GEq IORef where
|
2019-03-17 22:47:38 +01:00
|
|
|
a `geq` b = if a == unsafeCoerce b then Just $ unsafeCoerce Refl else Nothing
|
2019-03-11 16:04:15 +01:00
|
|
|
|
|
|
|
instance GEq (STRef s) where
|
2019-03-17 22:47:38 +01:00
|
|
|
a `geq` b = if a == unsafeCoerce b then Just $ unsafeCoerce Refl else Nothing
|