Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Synopsis
- class Referenceable letName sem where
- class Definable letName sem where
- define :: letName -> sem a -> sem a
- class MakeLetName letName where
- makeLetName :: SharingName -> IO letName
- data SharingName = forall a. SharingName (StableName a)
- makeSharingName :: a -> SharingName
- newtype SharingObserver letName sem a = SharingObserver {
- unSharingObserver :: ReaderT (HashSet SharingName) (State (SharingObserverState letName)) (SharingFinalizer letName sem a)
- observeSharing :: Eq letName => Hashable letName => Show letName => SharingObserver letName sem a -> WithSharing letName sem a
- type WithSharing letName sem a = (sem a, HashMap letName (SomeLet sem))
- data SharingObserverState letName = SharingObserverState {
- oss_refs :: HashMap SharingName (letName, Int)
- oss_recs :: HashSet SharingName
- observeSharingNode :: Eq letName => Hashable letName => Show letName => Referenceable letName sem => MakeLetName letName => SharingObserver letName sem a -> SharingObserver letName sem a
- newtype SharingFinalizer letName sem a = SharingFinalizer {
- unFinalizeSharing :: ReaderT (HashSet letName) (Writer (LetBindings letName sem)) (sem a)
- class Letsable letName sem where
- lets :: LetBindings letName sem -> sem a -> sem a
- data SomeLet sem = forall a. SomeLet (sem a)
- type LetBindings letName sem = HashMap letName (SomeLet sem)
- type OpenRecs letName a = LetRecs letName (OpenRec letName a)
- type OpenRec letName a = LetRecs letName a -> a
- type LetRecs letName = HashMap letName
- fix :: (a -> a) -> a
- mutualFix :: forall recs a. Functor recs => recs (recs a -> a) -> recs a
Class Referenceable
class Referenceable letName sem where Source #
This class is not for end-users like usual symantic operators, though it will have to be defined on end-users' interpreters.
Nothing
ref :: Bool -> letName -> sem a Source #
(
is a reference to ref
isRec letName)(letName)
.
It is introduced by observeSharing
.
(isRec)
is True
iif. this ref
erence is recursive,
ie. appears within its define
.
TODO: index letName
with a
to enable dependent-map
default ref :: FromDerived (Referenceable letName) sem => Bool -> letName -> sem a Source #
Instances
(Referenceable letName sem, Eq letName, Hashable letName, Show letName) => Referenceable letName (SharingFinalizer letName sem) Source # | |
Defined in Symantic.Semantics.SharingObserver ref :: Bool -> letName -> SharingFinalizer letName sem a Source # | |
Referenceable letName (SharingObserver letName sem) Source # | |
Defined in Symantic.Semantics.SharingObserver ref :: Bool -> letName -> SharingObserver letName sem a Source # |
Class Definable
class Definable letName sem where Source #
This class is not for end-users like usual symantic operators.
There should be not need to use it outside this module,
because used define
s are gathered in Letsable
.
Nothing
define :: letName -> sem a -> sem a Source #
(
let-binds define
letName sub)(letName)
to be equal to (sub)
.
This is a temporary node either replaced
by ref
and an entry in lets'
s LetBindings
,
or removed when no ref
erence is made to it.
default define :: FromDerived1 (Definable letName) sem => letName -> sem a -> sem a Source #
Instances
(Referenceable letName sem, Eq letName, Hashable letName, Show letName) => Definable letName (SharingFinalizer letName sem) Source # | |
Defined in Symantic.Semantics.SharingObserver define :: letName -> SharingFinalizer letName sem a -> SharingFinalizer letName sem a Source # | |
Definable letName (SharingObserver letName sem) Source # | |
Defined in Symantic.Semantics.SharingObserver define :: letName -> SharingObserver letName sem a -> SharingObserver letName sem a Source # |
Class MakeLetName
class MakeLetName letName where Source #
makeLetName :: SharingName -> IO letName Source #
Type SharingName
data SharingName Source #
Note that the observable sharing enabled by StableName
is not perfect as it will not observe all the sharing explicitely done.
Note also that the observed sharing could be different between ghc and ghci.
forall a. SharingName (StableName a) |
Instances
Eq SharingName Source # | |
Defined in Symantic.Semantics.SharingObserver (==) :: SharingName -> SharingName -> Bool # (/=) :: SharingName -> SharingName -> Bool # | |
Hashable SharingName Source # | |
Defined in Symantic.Semantics.SharingObserver hashWithSalt :: Int -> SharingName -> Int # hash :: SharingName -> Int # |
makeSharingName :: a -> SharingName Source #
(
is like makeSharingName
x)(
but it also forces
evaluation of makeStableName
x)(x)
to ensure that the StableName
is correct first time,
which avoids to produce a tree bigger than needed.
Note that this function uses unsafePerformIO
instead of returning in IO
,
this is apparently required to avoid infinite loops due to unstable StableName
in compiled code, and sometimes also in ghci.
Note that maybe pseq should be used here.
Type SharingObserver
newtype SharingObserver letName sem a Source #
SharingObserver | |
|
Instances
observeSharing :: Eq letName => Hashable letName => Show letName => SharingObserver letName sem a -> WithSharing letName sem a Source #
Interpreter detecting some (Haskell embedded) let
definitions used at
least once and/or recursively, in order to replace them
with the lets
and ref
combinators.
See Type-safe observable sharing in Haskell
Beware not to apply observeSharing
more than once on the same term
otherwise some define
introduced by the first call
would be removed by the second call.
Type WithSharing
type WithSharing letName sem a = (sem a, HashMap letName (SomeLet sem)) Source #
Type SharingObserverState
data SharingObserverState letName Source #
SharingObserverState | |
|
observeSharingNode :: Eq letName => Hashable letName => Show letName => Referenceable letName sem => MakeLetName letName => SharingObserver letName sem a -> SharingObserver letName sem a Source #
Type SharingFinalizer
newtype SharingFinalizer letName sem a Source #
SharingFinalizer | |
|
Instances
Class Letsable
class Letsable letName sem where Source #
Nothing
lets :: LetBindings letName sem -> sem a -> sem a Source #
(
let-binds lets
defs x)(defs)
in (x)
.
default lets :: Derivable sem => FromDerived1 (Letsable letName) sem => LetBindings letName sem -> sem a -> sem a Source #
Instances
Letsable letName (SharingObserver letName sem) Source # | |
Defined in Symantic.Semantics.SharingObserver lets :: LetBindings letName (SharingObserver letName sem) -> SharingObserver letName sem a -> SharingObserver letName sem a Source # |
Type SomeLet
Type LetBindings
type LetBindings letName sem = HashMap letName (SomeLet sem) Source #
Type OpenRecs
type OpenRecs letName a = LetRecs letName (OpenRec letName a) Source #
Mutually recursive terms, in open recursion style.
type OpenRec letName a = LetRecs letName a -> a Source #
Mutually recursive term, in open recursion style.
The term is given a final
(aka. self
) map
of other terms it can refer to (including itself).
mutualFix :: forall recs a. Functor recs => recs (recs a -> a) -> recs a Source #
Least fixpoint combinator of mutually recursive terms.
(
takes a container of terms
in the open recursion style mutualFix
opens)(opens)
,
and return that container of terms with their knots tied-up.
Used to express mutual recursion and to transparently introduce memoization.
Here all mutually dependent functions are restricted to the same polymorphic type (a)
.
See http://okmij.org/ftp/Computation/fixed-point-combinators.html#Poly-variadic