symantic-base-0.5.0.20221211: Basic symantic combinators for Embedded Domain-Specific Languages (EDSL)
Safe HaskellSafe-Inferred
LanguageHaskell2010

Symantic.Semantics.SharingObserver

Synopsis

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.

Minimal complete definition

Nothing

Methods

ref :: Bool -> letName -> sem a Source #

(ref isRec letName) is a reference to (letName). It is introduced by observeSharing. (isRec) is True iif. this reference 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

Instances details
(Referenceable letName sem, Eq letName, Hashable letName, Show letName) => Referenceable letName (SharingFinalizer letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

ref :: Bool -> letName -> SharingFinalizer letName sem a Source #

Referenceable letName (SharingObserver letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

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 defines are gathered in Letsable.

Minimal complete definition

Nothing

Methods

define :: letName -> sem a -> sem a Source #

(define letName sub) let-binds (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 reference is made to it.

default define :: FromDerived1 (Definable letName) sem => letName -> sem a -> sem a Source #

Instances

Instances details
(Referenceable letName sem, Eq letName, Hashable letName, Show letName) => Definable letName (SharingFinalizer letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

define :: letName -> SharingFinalizer letName sem a -> SharingFinalizer letName sem a Source #

Definable letName (SharingObserver letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

define :: letName -> SharingObserver letName sem a -> SharingObserver letName sem a Source #

Class MakeLetName

class MakeLetName letName where Source #

Methods

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.

Constructors

forall a. SharingName (StableName a) 

Instances

Instances details
Eq SharingName Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Hashable SharingName Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

makeSharingName :: a -> SharingName Source #

(makeSharingName x) is like (makeStableName x) but it also forces evaluation of (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 #

Instances

Instances details
Definable letName (SharingObserver letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

define :: letName -> SharingObserver letName sem a -> SharingObserver letName sem a Source #

Letsable letName (SharingObserver letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

lets :: LetBindings letName (SharingObserver letName sem) -> SharingObserver letName sem a -> SharingObserver letName sem a Source #

Referenceable letName (SharingObserver letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

ref :: Bool -> letName -> SharingObserver letName sem a Source #

(Referenceable letName sem, MakeLetName letName, Eq letName, Hashable letName, Show letName) => LiftDerived (SharingObserver letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

liftDerived :: Derived (SharingObserver letName sem) a -> SharingObserver letName sem a Source #

(Referenceable letName sem, MakeLetName letName, Eq letName, Hashable letName, Show letName) => LiftDerived1 (SharingObserver letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

liftDerived1 :: (Derived (SharingObserver letName sem) a -> Derived (SharingObserver letName sem) b) -> SharingObserver letName sem a -> SharingObserver letName sem b Source #

(Referenceable letName sem, MakeLetName letName, Eq letName, Hashable letName, Show letName) => LiftDerived2 (SharingObserver letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

liftDerived2 :: (Derived (SharingObserver letName sem) a -> Derived (SharingObserver letName sem) b -> Derived (SharingObserver letName sem) c) -> SharingObserver letName sem a -> SharingObserver letName sem b -> SharingObserver letName sem c Source #

(Referenceable letName sem, MakeLetName letName, Eq letName, Hashable letName, Show letName) => LiftDerived3 (SharingObserver letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

liftDerived3 :: (Derived (SharingObserver letName sem) a -> Derived (SharingObserver letName sem) b -> Derived (SharingObserver letName sem) c -> Derived (SharingObserver letName sem) d) -> SharingObserver letName sem a -> SharingObserver letName sem b -> SharingObserver letName sem c -> SharingObserver letName sem d Source #

(Referenceable letName sem, MakeLetName letName, Eq letName, Hashable letName, Show letName) => LiftDerived4 (SharingObserver letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

liftDerived4 :: (Derived (SharingObserver letName sem) a -> Derived (SharingObserver letName sem) b -> Derived (SharingObserver letName sem) c -> Derived (SharingObserver letName sem) d -> Derived (SharingObserver letName sem) e) -> SharingObserver letName sem a -> SharingObserver letName sem b -> SharingObserver letName sem c -> SharingObserver letName sem d -> SharingObserver letName sem e Source #

type Derived (SharingObserver letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

type Derived (SharingObserver letName sem) = SharingFinalizer letName sem

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

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 #

Remove define when non-recursive or unused or replace it by ref, moving defines to the top.

Constructors

SharingFinalizer 

Fields

Instances

Instances details
(Referenceable letName sem, Eq letName, Hashable letName, Show letName) => Definable letName (SharingFinalizer letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

define :: letName -> SharingFinalizer letName sem a -> SharingFinalizer letName sem a Source #

(Referenceable letName sem, Eq letName, Hashable letName, Show letName) => Referenceable letName (SharingFinalizer letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

ref :: Bool -> letName -> SharingFinalizer letName sem a Source #

(Eq letName, Hashable letName) => LiftDerived (SharingFinalizer letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

liftDerived :: Derived (SharingFinalizer letName sem) a -> SharingFinalizer letName sem a Source #

(Eq letName, Hashable letName) => LiftDerived1 (SharingFinalizer letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

liftDerived1 :: (Derived (SharingFinalizer letName sem) a -> Derived (SharingFinalizer letName sem) b) -> SharingFinalizer letName sem a -> SharingFinalizer letName sem b Source #

(Eq letName, Hashable letName) => LiftDerived2 (SharingFinalizer letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

liftDerived2 :: (Derived (SharingFinalizer letName sem) a -> Derived (SharingFinalizer letName sem) b -> Derived (SharingFinalizer letName sem) c) -> SharingFinalizer letName sem a -> SharingFinalizer letName sem b -> SharingFinalizer letName sem c Source #

(Eq letName, Hashable letName) => LiftDerived3 (SharingFinalizer letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

liftDerived3 :: (Derived (SharingFinalizer letName sem) a -> Derived (SharingFinalizer letName sem) b -> Derived (SharingFinalizer letName sem) c -> Derived (SharingFinalizer letName sem) d) -> SharingFinalizer letName sem a -> SharingFinalizer letName sem b -> SharingFinalizer letName sem c -> SharingFinalizer letName sem d Source #

(Eq letName, Hashable letName) => LiftDerived4 (SharingFinalizer letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

liftDerived4 :: (Derived (SharingFinalizer letName sem) a -> Derived (SharingFinalizer letName sem) b -> Derived (SharingFinalizer letName sem) c -> Derived (SharingFinalizer letName sem) d -> Derived (SharingFinalizer letName sem) e) -> SharingFinalizer letName sem a -> SharingFinalizer letName sem b -> SharingFinalizer letName sem c -> SharingFinalizer letName sem d -> SharingFinalizer letName sem e Source #

type Derived (SharingFinalizer _letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

type Derived (SharingFinalizer _letName sem) = sem

Class Letsable

class Letsable letName sem where Source #

Minimal complete definition

Nothing

Methods

lets :: LetBindings letName sem -> sem a -> sem a Source #

(lets defs x) let-binds (defs) in (x).

default lets :: Derivable sem => FromDerived1 (Letsable letName) sem => LetBindings letName sem -> sem a -> sem a Source #

Instances

Instances details
Letsable letName (SharingObserver letName sem) Source # 
Instance details

Defined in Symantic.Semantics.SharingObserver

Methods

lets :: LetBindings letName (SharingObserver letName sem) -> SharingObserver letName sem a -> SharingObserver letName sem a Source #

Type SomeLet

data SomeLet sem Source #

Constructors

forall a. SomeLet (sem a) 

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).

type LetRecs letName = HashMap letName Source #

Recursive let bindings.

fix :: (a -> a) -> a Source #

Least fixpoint combinator.

mutualFix :: forall recs a. Functor recs => recs (recs a -> a) -> recs a Source #

Least fixpoint combinator of mutually recursive terms. (mutualFix opens) takes a container of terms in the open recursion style (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