{-# LANGUAGE PackageImports #-} module FayRef (FayRef, newFayRef, readFayRef, writeFayRef, modifyFayRef, modifyFayRef') where import Prelude import FFI -- |A mutable variable in the 'Fay' monad. data FayRef a = FayRef -- |Build a new 'FayRef'. newFayRef :: a -> Fay (FayRef a) newFayRef = ffi "{contents: %1}" -- |Write a new value into a 'FayRef'. readFayRef :: FayRef a -> Fay a readFayRef = ffi "%1['contents']" -- |Write a new value into a 'FayRef'. writeFayRef :: FayRef a -> a -> Fay () writeFayRef = ffi "%1['contents']=%2" -- |Mutate the contents of a 'FayRef'. -- -- Be warned that 'modifyFayRef' does not apply the function strictly. This -- means if the program calls 'modifyFayRef' many times, but seldomly uses the -- value, thunks will pile up in memory resulting in a space leak. modifyFayRef :: FayRef a -> (a -> a) -> Fay () modifyFayRef ref f = readFayRef ref >>= (writeFayRef ref . f) -- |Strict version of 'modifyFayRef' modifyFayRef' :: FayRef a -> (a -> a) -> Fay () modifyFayRef' ref f = do x <- readFayRef ref let x' = f x writeFayRef ref $! x'