hnix/src/Nix/Var.hs

46 lines
1.1 KiB
Haskell

{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Nix.Var where
import Control.Monad.Ref
import Data.GADT.Compare
import Data.IORef
import Data.Maybe
import Data.STRef
import Unsafe.Coerce
type Var m = Ref m
type MonadVar m = MonadAtomicRef m
eqVar :: forall m a . GEq (Ref m) => Ref m a -> Ref m a -> Bool
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
a `geq` b = if a == unsafeCoerce b then Just $ unsafeCoerce Refl else Nothing
instance GEq (STRef s) where
a `geq` b = if a == unsafeCoerce b then Just $ unsafeCoerce Refl else Nothing