symantic-base-0.4.0.20211106: Basic symantic combinators for Embedded Domain-Specific Languages (EDSL)
Safe HaskellNone
LanguageHaskell2010

Symantic.SharingObserver

Synopsis

Class Referenceable

class Referenceable letName repr 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 -> repr 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) repr => Bool -> letName -> repr a Source #

Instances

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

Defined in Symantic.SharingObserver

Methods

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

Referenceable letName (SharingObserver letName repr) Source # 
Instance details

Defined in Symantic.SharingObserver

Methods

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

Class Definable

class Definable letName repr 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 -> repr a -> repr 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) repr => letName -> repr a -> repr a Source #

Instances

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

Defined in Symantic.SharingObserver

Methods

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

Definable letName (SharingObserver letName repr) Source # 
Instance details

Defined in Symantic.SharingObserver

Methods

define :: letName -> SharingObserver letName repr a -> SharingObserver letName repr 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.SharingObserver

Hashable SharingName Source # 
Instance details

Defined in Symantic.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 repr a Source #

Instances

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

Defined in Symantic.SharingObserver

Methods

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

Definable letName (SharingObserver letName repr) Source # 
Instance details

Defined in Symantic.SharingObserver

Methods

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

Referenceable letName (SharingObserver letName repr) Source # 
Instance details

Defined in Symantic.SharingObserver

Methods

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

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

Defined in Symantic.SharingObserver

Methods

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

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

Defined in Symantic.SharingObserver

Methods

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

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

Defined in Symantic.SharingObserver

Methods

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

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

Defined in Symantic.SharingObserver

Methods

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

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

Defined in Symantic.SharingObserver

Methods

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

type Derived (SharingObserver letName repr) Source # 
Instance details

Defined in Symantic.SharingObserver

type Derived (SharingObserver letName repr) = SharingFinalizer letName repr

observeSharing :: Eq letName => Hashable letName => Show letName => SharingObserver letName repr a -> WithSharing letName repr 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 repr a = (repr a, HashMap letName (SomeLet repr)) Source #

Type SharingObserverState

observeSharingNode :: Eq letName => Hashable letName => Show letName => Referenceable letName repr => MakeLetName letName => SharingObserver letName repr a -> SharingObserver letName repr a Source #

Type SharingFinalizer

newtype SharingFinalizer letName repr 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 repr, Eq letName, Hashable letName, Show letName) => Definable letName (SharingFinalizer letName repr) Source # 
Instance details

Defined in Symantic.SharingObserver

Methods

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

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

Defined in Symantic.SharingObserver

Methods

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

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

Defined in Symantic.SharingObserver

Methods

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

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

Defined in Symantic.SharingObserver

Methods

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

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

Defined in Symantic.SharingObserver

Methods

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

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

Defined in Symantic.SharingObserver

Methods

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

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

Defined in Symantic.SharingObserver

Methods

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

type Derived (SharingFinalizer _letName repr) Source # 
Instance details

Defined in Symantic.SharingObserver

type Derived (SharingFinalizer _letName repr) = repr

Class Letsable

class Letsable letName repr where Source #

Minimal complete definition

Nothing

Methods

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

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

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

Instances

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

Defined in Symantic.SharingObserver

Methods

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

Type SomeLet

data SomeLet repr Source #

Constructors

forall a. SomeLet (repr a) 

Type LetBindings

type LetBindings letName repr = HashMap letName (SomeLet repr) 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 #

Lest 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, between observed sharing (defLet, call, jump) and also between join points (defJoin, refJoin).

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