use symantic-base symantic-parser-0.2.0.20210703
authorJulien Moutinho <julm+symantic-parser@sourcephile.fr>
Sun, 11 Jul 2021 17:07:46 +0000 (19:07 +0200)
committerJulien Moutinho <julm+symantic-parser@sourcephile.fr>
Sun, 11 Jul 2021 19:59:40 +0000 (21:59 +0200)
24 files changed:
Makefile
ReadMe.md
default.nix
flake.lock
flake.nix
src/Symantic/Parser/Grammar.hs
src/Symantic/Parser/Grammar/Combinators.hs
src/Symantic/Parser/Grammar/Fixity.hs [deleted file]
src/Symantic/Parser/Grammar/ObserveSharing.hs
src/Symantic/Parser/Grammar/Optimize.hs
src/Symantic/Parser/Grammar/Production.hs
src/Symantic/Parser/Grammar/View.hs
src/Symantic/Parser/Grammar/Write.hs
src/Symantic/Parser/Machine/Generate.hs
src/Symantic/Parser/Machine/Optimize.hs
src/Symantic/Parser/Machine/Program.hs
src/Symantic/Parser/Machine/View.hs
src/Symantic/Typed/Data.hs [deleted file]
src/Symantic/Typed/Lang.hs [deleted file]
src/Symantic/Typed/Letable.hs [deleted file]
src/Symantic/Typed/Optim.hs [deleted file]
src/Symantic/Typed/Trans.hs [deleted file]
src/Symantic/Typed/View.hs [deleted file]
symantic-parser.cabal

index d1c9dc6e3cd6bce1abadf201418aa9734294a644..5735b7a930e6532adabd49b583d7b9db5d1c2d65 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 override RTS_OPTIONS += -L100
 override TEST_OPTIONS += --color always --size-cutoff 1000000 $(addprefix -p ,$t)
-override GHC_PROF_OPTIONS += -fprof-auto -fprof-auto-calls
+override GHC_PROF_OPTIONS += -eventlog -fprof-auto -fprof-auto-calls
 override BENCHMARK_OPTIONS += --output benchmarks/html/$(version).html --match glob $b
 override REPL_OPTIONS += -ignore-dot-ghci
 
index dd9034e989cdb9bf92ec6a9d0251aa86c38d4564..23b7f66a9fe91bf3d7b1a51336b428c166b707ca 100644 (file)
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -1,23 +1,35 @@
 ### Main differences with respect to `ParsleyHaskell`
 
-- Extensible primitive grammar combinators, including their underlying optimization passes, by leveraging reciprocal injections between a tagless-final encoding of syntaxes (aka. type-classes) and a corresponding tagged-initial encoding to pattern-match syntaxes (aka. data-instances). This is a final approach to recursion patterns, whereas [recursion-schemes](http://hackage.haskell.org/package/recursion-schemes) is an initial one. Here `DefaultSignatures` are supplied to succinctly derive new semantics (aka. type-class-instances) using automatic `trans`formations.
+- Primitive grammar combinators are extensible, including the optimization pass for which they are the current top-level combinator.
 
-- Error messages based upon the farthest input position reached (not yet implemented in `ParsleyHaskell`).
+- Error messages are based upon the farthest input position reached (not yet implemented in `ParsleyHaskell`) and a there is a preliminary support for error messages based upon [labeled failures](https://dl.acm.org/doi/10.1145/2851613.2851750).
 
-- Minimal input length checks ("horizon" checks) required for a successful parsing are factorized using a different static analysis than `ParsleyHaskell`'s "piggy bank" which I've not understood well. This analysis uses [polyfix](http://okmij.org/ftp/Computation/fixed-point-combinators.html#Poly-variadic) to see beyond calls to subroutines.
+- Minimal input length checks ("horizon" checks) required for a successful parsing are statically computed using a [polyfix](http://okmij.org/ftp/Computation/fixed-point-combinators.html#Poly-variadic) to see beyond calls to subroutines, which is not (yet) possible in `ParsleyHaskell`.
 
-- No dependency upon GHC plugins: `lift-plugin`, `idioms-plugin` or `parsley-garnish`. Because those are plugins hence introduce a bit of complexity in the build processes using this parser, but most importantly they are experimental and mostly cosmetics, since they only enable a cleaner usage of the parsing combinators: by quoting an Haskell expression as itself and its `TemplateHaskell` equivalent. I do not understand them that much and do not feel confortable to maintain them come the day that their authors abandon them.
+- No dependency upon GHC plugins: `lift-plugin`, `idioms-plugin` or `parsley-garnish` for users. Those provide convenient syntaxic-sugar (by quoting an Haskell expression as itself and its `TemplateHaskell` equivalent) for writing grammar productions, but are experimental, but I do not understand them that much and do not feel confortable to maintain them in case their authors abandon them.
 
-- No dependency upon `dependent-map` by keeping observed sharing inside `def` and `ref` combinators, instead of passing by a `DMap`. And also when introducing the join-points optimization, where fresh `TemplateHaskell` names are also directly used instead of passing by a `DMap`.
+- No dependency upon `dependent-map` by keeping observed sharing in `def` and `ref` combinators, instead of passing by a `DMap`. And also when introducing the join-points optimization, where fresh `TemplateHaskell` names are also directly used instead of passing by a `DMap`.
 
-- No support (yet?) for general purpose registers in the `Machine` producing the `TemplateHaskell` splices.
+- No support (yet?) for general purpose registers in the `Machine` producing the `TemplateHaskell` splices. Hence `symantic-parser` generates parser much slower than `ParsleyHaskell`, comparable to `attoparsec` in the Brainfuck benchmark.
 
 - License is `AGPL-3-or-later` not `BSD-3-Clause`.
 
-- Some generated `TemplateHaskell` is followed by golden tests.
+- Testing grammars have their generated machines and `TemplateHaskell` splices followed by golden tests.
 
 ### Main goals
 
 - For me to better understand [ParsleyHaskell](https://github.com/j-mie6/ParsleyHaskell), and find a manageable balance between simplicity of the codebase and features of the parser. And by doing so, challenging and showcasing symantic techniques.
 
 - To support the parsing of tree-like data structures instead of only string-like data structures. Eg. to validate XML using RelaxNG in [symantic-xml](https://hackage.haskell.org/package/symantic-xml) or to perform routing of HTTP requests in [symantic-http-server](http://hackage.haskell.org/package/symantic-http-server). This is currently done in those packages using `megaparsec`, but `megaparsec` is not conceived for such input, and is less principled when it comes to optimizing, like merging alternatives.
+
+### Implementation techniques
+
+#### Typed Tagless-Final
+The syntax of grammars are term-level combinators defined in type-classes,
+and their semantics are data-types having instances of those type-classes.
+And the same technique is applied for machine instructions and grammar productions.
+
+For automatic deriving, `DefaultSignatures` are supplied using automatic `trans`formations, see `Symantic.Typed.Trans`.
+
+For pattern-matching, data-families indexed by the syntaxic type-class are supplied,
+see `Symantic.Typed.Data`.
index f599f8a1431dfad46b3a97cb59b84172b9da9707..db14da0c149cec7862cf74deffce047b5802a48f 100644 (file)
@@ -1,6 +1,7 @@
 { pkgs ? import <nixpkgs> {}
 , ghc ? "ghc901"
 , withHoogle ? false
+, inputs
 }:
 let
   haskellPackages =
@@ -16,13 +17,16 @@ let
       hs-speedscope = doJailbreak (unmarkBroken hsuper.hs-speedscope);
       eventlog2html = doJailbreak (unmarkBroken hsuper.eventlog2html);
       trie-simple = doJailbreak (unmarkBroken hsuper.trie-simple);
-      symantic-parser = buildFromSdist (hself.callCabal2nix "symantic-parser" ./. {});
+      symantic-base = buildFromSdist (hself.callCabal2nix "symantic-base" inputs.symantic-base {});
+      symantic-parser = doBenchmark (buildFromSdist (hself.callCabal2nix "symantic-parser" ./. {}));
+      /*
       hlint = hsuper.hlint_3_3_1.overrideScope (self: super: {
         ghc-lib-parser = overrideCabal self.ghc-lib-parser_9_0_1_20210324 {
           doHaddock = false;
         };
         ghc-lib-parser-ex = self.ghc-lib-parser-ex_9_0_0_4;
       });
+      */
     }
   );
 in hs.symantic-parser // {
@@ -36,7 +40,7 @@ in hs.symantic-parser // {
       hs.eventlog2html
       hs.ghc-events
       hs.ghcid
-      hs.hlint
+      #hs.hlint
       hs.hs-speedscope
       hs.ormolu
       hs.profiteur
index c3d33bbead73711482f7fbcd6c41bb53e2134a60..e85fe530ceeb4237b240184b33995c5748f92f84 100644 (file)
         "type": "github"
       }
     },
+    "flake-utils_2": {
+      "locked": {
+        "lastModified": 1623875721,
+        "narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "f7e004a55b120c02ecb6219596820fcd32ca8772",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
     "nixpkgs": {
       "locked": {
         "narHash": "sha256-3C35/g5bJ3KH67fOpxTkqDpfJ1CHYrO2bbl+fPgqfMQ=",
     "root": {
       "inputs": {
         "flake-utils": "flake-utils",
-        "nixpkgs": "nixpkgs"
+        "nixpkgs": "nixpkgs",
+        "symantic-base": "symantic-base"
+      }
+    },
+    "symantic-base": {
+      "inputs": {
+        "flake-utils": "flake-utils_2",
+        "nixpkgs": [
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1626033315,
+        "narHash": "sha256-vHRFhc9Bg2cxrAR9R1TSXn2f6ZwzOIMRD+0n3cXzl54=",
+        "ref": "master",
+        "rev": "29078a0e7fbe8df3204bcf86dd902a301072574f",
+        "revCount": 14,
+        "type": "git",
+        "url": "git://git.sourcephile.fr/haskell/symantic-base"
+      },
+      "original": {
+        "type": "git",
+        "url": "git://git.sourcephile.fr/haskell/symantic-base"
       }
     }
   },
index 494305fd730ac34b83683f2ed296725f1b96387d..997a2602e79d71ebd3a3c7eaa59e3ef3c46caa63 100644 (file)
--- a/flake.nix
+++ b/flake.nix
@@ -1,12 +1,15 @@
 {
 inputs.nixpkgs.url = "flake:nixpkgs";
+#inputs.nixpkgs.url = "github:NixOS/nixpkgs";
 inputs.flake-utils.url = "github:numtide/flake-utils";
+inputs.symantic-base.url = "git://git.sourcephile.fr/haskell/symantic-base";
+inputs.symantic-base.inputs.nixpkgs.follows = "nixpkgs";
 outputs = inputs:
   inputs.flake-utils.lib.eachDefaultSystem (system: let
     pkgs = inputs.nixpkgs.legacyPackages.${system};
     in {
-      defaultPackage = import ./default.nix { inherit pkgs; };
-      devShell = (import ./default.nix { inherit pkgs; }).shell;
+      defaultPackage = import ./default.nix { inherit inputs pkgs; };
+      devShell = (import ./default.nix { inherit inputs pkgs; }).shell;
     }
   );
 }
index f734161d076e9ae744d338e7f249e1f1b6364681..a99964e73768a71360aa4742c90916a21bd3104f 100644 (file)
@@ -3,7 +3,6 @@
 module Symantic.Parser.Grammar
   ( module Symantic.Parser.Grammar
   , module Symantic.Parser.Grammar.Combinators
-  , module Symantic.Parser.Grammar.Fixity
   , module Symantic.Parser.Grammar.Optimize
   , module Symantic.Parser.Grammar.ObserveSharing
   , module Symantic.Parser.Grammar.Production
@@ -13,7 +12,6 @@ module Symantic.Parser.Grammar
   , Letsable(..)
   ) where
 import Symantic.Parser.Grammar.Combinators
-import Symantic.Parser.Grammar.Fixity
 import Symantic.Parser.Grammar.ObserveSharing
 import Symantic.Parser.Grammar.Optimize
 import Symantic.Parser.Grammar.Production
index 71c5c32e29d431ab3a048b79442f4038fe3e9dad..ae2494bf8bad012d3e101c23f6e79e551e5956ec 100644 (file)
@@ -1,7 +1,7 @@
 -- The default type signature of type class methods are changed
--- to introduce a 'Liftable' constraint and the same type class but on the 'Unlifted' repr,
+-- to introduce a 'LiftDerived'* constraint and the same type class but on the 'Derived' repr,
 -- this setup avoids to define the method with boilerplate code when its default
--- definition with lift* and 'trans' does what is expected by an instance
+-- definition with 'liftDerived'* and 'derive' does what is expected by an instance
 -- of the type class. This is almost as explained in:
 -- https://ro-che.info/articles/2016-02-03-finally-tagless-boilerplate
 {-# LANGUAGE DefaultSignatures #-}
@@ -42,7 +42,7 @@ import qualified Data.Set as Set
 import qualified Language.Haskell.TH as TH
 import qualified Language.Haskell.TH.Syntax as TH
 
-import qualified Symantic.Typed.Trans as Sym
+import Symantic.Typed.Derive
 import qualified Symantic.Typed.Lang as Prod
 import Symantic.Parser.Grammar.Production
 
@@ -64,23 +64,23 @@ class CombAlternable repr where
   -- Generally used on the first alternative: @('try' rl '<|>' rr)@.
   try :: repr a -> repr a
   default alt ::
-    Sym.Liftable2 repr => CombAlternable (Sym.Unlifted repr) =>
+    FromDerived2 CombAlternable repr =>
     Exception -> repr a -> repr a -> repr a
   default throw ::
-    Sym.Liftable repr => CombAlternable (Sym.Unlifted repr) =>
+    FromDerived CombAlternable repr =>
     ExceptionLabel -> repr a
   default try ::
-    Sym.Liftable1 repr => CombAlternable (Sym.Unlifted repr) =>
+    FromDerived1 CombAlternable repr =>
     repr a -> repr a
-  alt = Sym.lift2 . alt
-  throw = Sym.lift . throw
-  try = Sym.lift1 try
+  alt = liftDerived2 . alt
+  throw = liftDerived . throw
+  try = liftDerived1 try
 
   failure :: SomeFailure -> repr a
   default failure ::
-    Sym.Liftable repr => CombAlternable (Sym.Unlifted repr) =>
+    FromDerived CombAlternable repr =>
     SomeFailure -> repr a
-  failure = Sym.lift . failure
+  failure = liftDerived . failure
 
   -- | @(empty)@ parses nothing, always failing to return a value.
   empty :: repr a
@@ -106,8 +106,7 @@ pattern Failure x <- (unSomeFailure -> Just x)
 -- ** Type 'SomeFailure'
 data SomeFailure =
   forall comb.
-  ({-Trans (Failure comb repr) repr,-}
-    Eq (Failure comb)
+  ( Eq (Failure comb)
   , Ord (Failure comb)
   , Show (Failure comb)
   , TH.Lift (Failure comb)
@@ -140,8 +139,8 @@ instance NFData SomeFailure where
   rnf (SomeFailure x) = rnf x
 
 {-
-instance Trans (SomeFailure repr) repr where
-  trans (SomeFailure x) = trans x
+instance Derivable (SomeFailure repr) where
+  derive (SomeFailure x) = derive x
 -}
 
 -- | @(unSomeFailure c :: 'Maybe' ('Failure' comb repr a))@
@@ -221,18 +220,18 @@ class CombApplicable repr where
   -- | @('pure' a)@ parses the empty string, always succeeding in returning @(a)@.
   pure :: Production a -> repr a
   default pure ::
-    Sym.Liftable repr => CombApplicable (Sym.Unlifted repr) =>
+    FromDerived CombApplicable repr =>
     Production a -> repr a
-  pure = Sym.lift . pure
+  pure = liftDerived . pure
 
   -- | @(ra2b '<*>' ra)@ parses sequentially @(ra2b)@ and then @(ra)@,
   -- and returns the application of the function returned by @(ra2b)@
   -- to the value returned by @(ra)@.
   (<*>) :: repr (a -> b) -> repr a -> repr b
   default (<*>) ::
-    Sym.Liftable2 repr => CombApplicable (Sym.Unlifted repr) =>
+    FromDerived2 CombApplicable repr =>
     repr (a -> b) -> repr a -> repr b
-  (<*>) = Sym.lift2 (<*>)
+  (<*>) = liftDerived2 (<*>)
 
   -- | @(ra '<*' rb)@ parses sequentially @(ra)@ and then @(rb)@,
   -- and returns like @(ra)@, discarding the return value of @(rb)@.
@@ -291,13 +290,13 @@ class CombFoldable repr where
   chainPost :: repr a -> repr (a -> a) -> repr a
   {-
   default chainPre ::
-    Sym.Liftable2 repr => CombFoldable (Sym.Unlifted repr) =>
+    FromDerived2 CombFoldable repr =>
     repr (a -> a) -> repr a -> repr a
   default chainPost ::
-    Sym.Liftable2 repr => CombFoldable (Sym.Unlifted repr) =>
+    FromDerived2 CombFoldable repr =>
     repr a -> repr (a -> a) -> repr a
-  chainPre = Sym.lift2 chainPre
-  chainPost = Sym.lift2 chainPost
+  chainPre = liftDerived2 chainPre
+  chainPost = liftDerived2 chainPost
   -}
   default chainPre ::
     CombApplicable repr =>
@@ -451,9 +450,9 @@ class CombMatchable repr where
   conditional ::
     Eq a => repr a -> [Production (a -> Bool)] -> [repr b] -> repr b -> repr b
   default conditional ::
-    Sym.Unliftable repr => Sym.Liftable1 repr => CombMatchable (Sym.Unlifted repr) =>
+    FromDerived1 CombMatchable repr => Derivable repr =>
     Eq a => repr a -> [Production (a -> Bool)] -> [repr b] -> repr b -> repr b
-  conditional a ps bs = Sym.lift1 (conditional (Sym.unlift a) ps (Sym.unlift Functor.<$> bs))
+  conditional a ps bs = liftDerived1 (conditional (derive a) ps (derive Functor.<$> bs))
 
   match :: Eq a => repr a -> [Production a] -> (Production a -> repr b) -> repr b -> repr b
   match a as a2b = conditional a ((Prod.equal Prod..@) Functor.<$> as) (a2b Functor.<$> as)
@@ -470,10 +469,10 @@ class CombSatisfiable tok repr where
     Set SomeFailure ->
     Production (tok -> Bool) -> repr tok
   default satisfyOrFail ::
-    Sym.Liftable repr => CombSatisfiable tok (Sym.Unlifted repr) =>
+    FromDerived (CombSatisfiable tok) repr =>
     Set SomeFailure ->
     Production (tok -> Bool) -> repr tok
-  satisfyOrFail fs = Sym.lift . satisfyOrFail fs
+  satisfyOrFail fs = liftDerived . satisfyOrFail fs
 
 data instance Failure (CombSatisfiable tok)
   =  FailureAny
@@ -585,23 +584,29 @@ tokens = try . traverse token
 class CombSelectable repr where
   branch :: repr (Either a b) -> repr (a -> c) -> repr (b -> c) -> repr c
   default branch ::
-    Sym.Liftable3 repr => CombSelectable (Sym.Unlifted repr) =>
+    FromDerived3 CombSelectable repr =>
     repr (Either a b) -> repr (a -> c) -> repr (b -> c) -> repr c
-  branch = Sym.lift3 branch
+  branch = liftDerived3 branch
 data instance Failure CombSelectable
 
 -- * Class 'CombLookable'
 class CombLookable repr where
   look :: repr a -> repr a
   negLook :: repr a -> repr ()
-  default look :: Sym.Liftable1 repr => CombLookable (Sym.Unlifted repr) => repr a -> repr a
-  default negLook :: Sym.Liftable1 repr => CombLookable (Sym.Unlifted repr) => repr a -> repr ()
-  look = Sym.lift1 look
-  negLook = Sym.lift1 negLook
+  default look ::
+    FromDerived1 CombLookable repr =>
+    repr a -> repr a
+  default negLook ::
+    FromDerived1 CombLookable repr =>
+    repr a -> repr ()
+  look = liftDerived1 look
+  negLook = liftDerived1 negLook
 
   eof :: repr ()
-  eof = Sym.lift eof
-  default eof :: Sym.Liftable repr => CombLookable (Sym.Unlifted repr) => repr ()
+  eof = liftDerived eof
+  default eof ::
+    FromDerived CombLookable repr =>
+    repr ()
   -- eof = negLook (satisfy @Char (Prod.const Prod..@ Prod.bool True))
              -- (item @Char)
 data instance Failure CombLookable
diff --git a/src/Symantic/Parser/Grammar/Fixity.hs b/src/Symantic/Parser/Grammar/Fixity.hs
deleted file mode 100644 (file)
index 70f1dbb..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-module Symantic.Parser.Grammar.Fixity where
-
-import Data.Bool
-import Data.Eq (Eq(..))
-import Data.Function ((.))
-import Data.Int (Int)
-import Data.Maybe (Maybe(..))
-import Data.Ord (Ord(..))
-import Data.Semigroup
-import Data.String (String, IsString(..))
-import Text.Show (Show(..))
-
--- * Type 'Fixity'
-data Fixity
- =   Fixity1 Unifix
- |   Fixity2 Infix
- deriving (Eq, Show)
-
--- ** Type 'Unifix'
-data Unifix
- =   Prefix  { unifix_precedence :: Precedence }
- |   Postfix { unifix_precedence :: Precedence }
- deriving (Eq, Show)
-
--- ** Type 'Infix'
-data Infix
- =   Infix
- {   infix_associativity :: Maybe Associativity
- ,   infix_precedence    :: Precedence
- } deriving (Eq, Show)
-
-infixL :: Precedence -> Infix
-infixL = Infix (Just AssocL)
-
-infixR :: Precedence -> Infix
-infixR = Infix (Just AssocR)
-
-infixB :: Side -> Precedence -> Infix
-infixB = Infix . Just . AssocB
-
-infixN :: Precedence -> Infix
-infixN = Infix Nothing
-
-infixN0 :: Infix
-infixN0 = infixN 0
-
-infixN5 :: Infix
-infixN5 = infixN 5
-
--- | Given 'Precedence' and 'Associativity' of its parent operator,
--- and the operand 'Side' it is in,
--- return whether an 'Infix' operator
--- needs to be enclosed by a 'Pair'.
-isPairNeeded :: (Infix, Side) -> Infix -> Bool
-isPairNeeded (po, lr) op =
-  infix_precedence op < infix_precedence po
-  || infix_precedence op == infix_precedence po
-  && not associate
-  where
-  associate =
-    case (lr, infix_associativity po) of
-     (_, Just AssocB{})   -> True
-     (SideL, Just AssocL) -> True
-     (SideR, Just AssocR) -> True
-     _ -> False
-
--- | If 'isPairNeeded' is 'True',
--- enclose the given 'IsString' by given 'Pair',
--- otherwise returns the same 'IsString'.
-pairIfNeeded ::
- Semigroup s => IsString s =>
- Pair -> (Infix, Side) -> Infix ->
- s -> s
-pairIfNeeded (o,c) po op s =
-  if isPairNeeded po op
-  then fromString o <> s <> fromString c
-  else s
-
--- * Type 'Precedence'
-type Precedence = Int
-
--- ** Class 'PrecedenceOf'
-class PrecedenceOf a where
-  precedence :: a -> Precedence
-instance PrecedenceOf Fixity where
-  precedence (Fixity1 uni) = precedence uni
-  precedence (Fixity2 inf) = precedence inf
-instance PrecedenceOf Unifix where
-  precedence = unifix_precedence
-instance PrecedenceOf Infix where
-  precedence = infix_precedence
-
--- * Type 'Associativity'
-data Associativity
- =   AssocL      -- ^ Associate to the left:  @a ¹ b ² c == (a ¹ b) ² c@
- |   AssocR      -- ^ Associate to the right: @a ¹ b ² c == a ¹ (b ² c)@
- |   AssocB Side -- ^ Associate to both sides, but to 'Side' when reading.
- deriving (Eq, Show)
-
--- ** Type 'Side'
-data Side
- =   SideL -- ^ Left
- |   SideR -- ^ Right
- deriving (Eq, Show)
-
--- ** Type 'Pair'
-type Pair = (String, String)
-pairAngle   :: Pair
-pairBrace   :: Pair
-pairBracket :: Pair
-pairParen   :: Pair
-pairAngle   = ("<",">")
-pairBrace   = ("{","}")
-pairBracket = ("[","]")
-pairParen   = ("(",")")
index 9851245482120cf3717a67ba32cea373521b917a..501878ad1d4bddcf0f0c2bc92c096c72ddaaa85c 100644 (file)
@@ -1,6 +1,6 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module Symantic.Parser.Grammar.ObserveSharing
-  ( module Symantic.Typed.Letable
+  ( module Symantic.Typed.ObserveSharing
   , module Symantic.Parser.Grammar.ObserveSharing
   ) where
 
@@ -11,17 +11,17 @@ import Text.Show (Show(..))
 import qualified Control.Applicative as Functor
 
 import Symantic.Parser.Grammar.Combinators
-import Symantic.Typed.Letable hiding (observeSharing)
-import qualified Symantic.Typed.Letable as Letable
+import Symantic.Typed.Derive
+import Symantic.Typed.ObserveSharing hiding (observeSharing)
+import qualified Symantic.Typed.ObserveSharing as ObserveSharing
 import qualified Language.Haskell.TH.Syntax as TH
-import qualified Symantic.Typed.Trans as Sym
 
--- | Like 'Letable.observeSharing'
+-- | Like 'Observable.observeSharing'
 -- but type-binding @(letName)@ to 'TH.Name'
 -- to avoid the trouble to always set it.
 observeSharing :: Letsable TH.Name repr => ObserveSharing TH.Name repr a -> repr a
 observeSharing os = lets defs body
-  where (body, defs) = Letable.observeSharing os
+  where (body, defs) = ObserveSharing.observeSharing os
 
 -- | Needed by 'observeSharing'.
 instance Hashable TH.Name where
@@ -38,7 +38,7 @@ instance
   ( Letable TH.Name repr
   , CombFoldable repr
   {- TODO: the following constraints are for the current CombFoldable,
-   - they will have to be removed when CombFoldable will have Sym.lift2 as defaults
+   - they will have to be removed when CombFoldable will have 'liftDerived2' as defaults
    -}
   , CombApplicable repr
   , CombAlternable repr
@@ -66,8 +66,8 @@ instance (Letable TH.Name repr, CombSatisfiable tok repr) =>
 instance CombApplicable repr => CombApplicable (FinalizeSharing TH.Name repr)
 instance CombAlternable repr => CombAlternable (FinalizeSharing TH.Name repr)
 instance CombFoldable repr => CombFoldable (FinalizeSharing TH.Name repr) where
-  chainPre = Sym.lift2 chainPre
-  chainPost = Sym.lift2 chainPost
+  chainPre = liftDerived2 chainPre
+  chainPost = liftDerived2 chainPost
 instance CombLookable repr => CombLookable (FinalizeSharing TH.Name repr)
 instance CombMatchable repr => CombMatchable (FinalizeSharing TH.Name repr) where
   conditional a cs bs b = FinalizeSharing $
index 3d5c19184a2e5f847807d3b3f3ab32035222228d..6d95114001189c1141ffff47cb60327850b6e8d4 100644 (file)
@@ -22,8 +22,8 @@ import qualified Data.List as List
 
 import Symantic.Parser.Grammar.Combinators
 import Symantic.Parser.Grammar.Production
-import Symantic.Typed.Letable
-import Symantic.Typed.Trans
+import Symantic.Typed.Derive
+import Symantic.Typed.ObserveSharing
 import qualified Symantic.Typed.Data as Prod
 import qualified Symantic.Typed.Lang as Prod
 
@@ -39,9 +39,9 @@ infix 0 &
 type OptimizeGrammar = SomeComb
 
 optimizeGrammar ::
-  Trans (SomeComb repr) repr =>
+  Derivable (SomeComb repr) =>
   SomeComb repr a -> repr a
-optimizeGrammar = trans
+optimizeGrammar = derive
 
 -- * Data family 'Comb'
 -- | 'Comb'inators of the 'Grammar'.
@@ -49,6 +49,7 @@ optimizeGrammar = trans
 data family Comb
   (comb :: ReprComb -> Constraint)
   :: ReprComb -> ReprComb
+type instance Derived (Comb comb repr) = repr
 
 -- | Convenient utility to pattern-match a 'SomeComb'.
 pattern Comb :: Typeable comb => Comb comb repr a -> SomeComb repr a
@@ -67,11 +68,12 @@ pattern Comb x <- (unSomeComb -> Just x)
 -- this also give a more understandable code.
 data SomeComb repr a =
   forall comb.
-  (Trans (Comb comb repr) repr, Typeable comb) =>
+  (Derivable (Comb comb repr), Typeable comb) =>
   SomeComb (Comb comb repr a)
 
-instance Trans (SomeComb repr) repr where
-  trans (SomeComb x) = trans x
+type instance Derived (SomeComb repr) = repr
+instance Derivable (SomeComb repr) where
+  derive (SomeComb x) = derive x
 
 -- | @(unSomeComb c :: 'Maybe' ('Comb' comb repr a))@
 -- extract the data-constructor from the given 'SomeComb'
@@ -92,13 +94,13 @@ data instance Comb CombAlternable repr a where
   Failure :: SomeFailure -> Comb CombAlternable repr a
   Throw :: ExceptionLabel -> Comb CombAlternable repr a
   Try :: SomeComb repr a -> Comb CombAlternable repr a
-instance CombAlternable repr => Trans (Comb CombAlternable repr) repr where
-  trans = \case
-    Alt exn x y -> alt exn (trans x) (trans y)
+instance CombAlternable repr => Derivable (Comb CombAlternable repr) where
+  derive = \case
+    Alt exn x y -> alt exn (derive x) (derive y)
     Empty -> empty
     Failure sf -> failure sf
     Throw exn -> throw exn
-    Try x -> try (trans x)
+    Try x -> try (derive x)
 instance
   ( CombAlternable repr
   , CombApplicable repr
@@ -142,12 +144,12 @@ pattern (:<$>:) :: Production (a -> b) -> SomeComb repr a -> Comb CombApplicable
 pattern t :<$>: x <- Comb (Pure t) :<*>: x
 pattern (:$>:) :: SomeComb repr a -> Production b -> Comb CombApplicable repr b
 pattern x :$>: t <- x :*>: Comb (Pure t)
-instance CombApplicable repr => Trans (Comb CombApplicable repr) repr where
-  trans = \case
+instance CombApplicable repr => Derivable (Comb CombApplicable repr) where
+  derive = \case
     Pure x -> pure (optimizeProduction x)
-    f :<*>: x -> trans f <*> trans x
-    x :<*: y -> trans x <* trans y
-    x :*>: y -> trans x *> trans y
+    f :<*>: x -> derive f <*> derive x
+    x :<*: y -> derive x <* derive y
+    x :*>: y -> derive x *> derive y
 instance
   ( CombApplicable repr
   , CombAlternable repr
@@ -233,10 +235,10 @@ instance
 data instance Comb CombFoldable repr a where
   ChainPreC :: SomeComb repr (a -> a) -> SomeComb repr a -> Comb CombFoldable repr a
   ChainPostC :: SomeComb repr a -> SomeComb repr (a -> a) -> Comb CombFoldable repr a
-instance CombFoldable repr => Trans (Comb CombFoldable repr) repr where
-  trans = \case
-    ChainPreC x y -> chainPre (trans x) (trans y)
-    ChainPostC x y -> chainPost (trans x) (trans y)
+instance CombFoldable repr => Derivable (Comb CombFoldable repr) where
+  derive = \case
+    ChainPreC x y -> chainPre (derive x) (derive y)
+    ChainPostC x y -> chainPost (derive x) (derive y)
 instance CombFoldable repr => CombFoldable (SomeComb repr) where
   chainPre x = SomeComb . ChainPreC x
   chainPost x = SomeComb . ChainPostC x
@@ -247,9 +249,9 @@ data instance Comb (Letable letName) repr a where
   Ref :: Bool -> letName -> Comb (Letable letName) repr a
 instance
   Letable letName repr =>
-  Trans (Comb (Letable letName) repr) repr where
-  trans = \case
-    Shareable n x -> shareable n (trans x)
+  Derivable (Comb (Letable letName) repr) where
+  derive = \case
+    Shareable n x -> shareable n (derive x)
     Ref isRec n -> ref isRec n
 instance
   (Letable letName repr, Typeable letName) =>
@@ -263,9 +265,9 @@ data instance Comb (Letsable letName) repr a where
           SomeComb repr a -> Comb (Letsable letName) repr a
 instance
   Letsable letName repr =>
-  Trans (Comb (Letsable letName) repr) repr where
-  trans = \case
-    Lets defs x -> lets ((\(SomeLet sub) -> SomeLet (trans sub)) Functor.<$> defs) (trans x)
+  Derivable (Comb (Letsable letName) repr) where
+  derive = \case
+    Lets defs x -> lets ((\(SomeLet sub) -> SomeLet (derive sub)) Functor.<$> defs) (derive x)
 instance
   (Letsable letName repr, Typeable letName) =>
   Letsable letName (SomeComb repr) where
@@ -276,10 +278,10 @@ data instance Comb CombLookable repr a where
   Look :: SomeComb repr a -> Comb CombLookable repr a
   NegLook :: SomeComb repr a -> Comb CombLookable repr ()
   Eof :: Comb CombLookable repr ()
-instance CombLookable repr => Trans (Comb CombLookable repr) repr where
-  trans = \case
-    Look x -> look (trans x)
-    NegLook x -> negLook (trans x)
+instance CombLookable repr => Derivable (Comb CombLookable repr) where
+  derive = \case
+    Look x -> look (derive x)
+    NegLook x -> negLook (derive x)
     Eof -> eof
 instance
   ( CombAlternable repr
@@ -329,12 +331,12 @@ data instance Comb CombMatchable repr a where
     [SomeComb repr b] ->
     SomeComb repr b ->
     Comb CombMatchable repr b
-instance CombMatchable repr => Trans (Comb CombMatchable repr) repr where
-  trans = \case
+instance CombMatchable repr => Derivable (Comb CombMatchable repr) where
+  derive = \case
     Conditional a ps bs b ->
-      conditional (trans a)
+      conditional (derive a)
         (optimizeProduction Functor.<$> ps)
-        (trans Functor.<$> bs) (trans b)
+        (derive Functor.<$> bs) (derive b)
 instance
   ( CombApplicable repr
   , CombAlternable repr
@@ -373,8 +375,8 @@ data instance Comb (CombSatisfiable tok) repr a where
     Comb (CombSatisfiable tok) repr tok
 instance
   CombSatisfiable tok repr =>
-  Trans (Comb (CombSatisfiable tok) repr) repr where
-  trans = \case
+  Derivable (Comb (CombSatisfiable tok) repr) where
+  derive = \case
     SatisfyOrFail fs p -> satisfyOrFail fs (optimizeProduction p)
 instance
   (CombSatisfiable tok repr, Typeable tok) =>
@@ -388,9 +390,9 @@ data instance Comb CombSelectable repr a where
     SomeComb repr (a -> c) ->
     SomeComb repr (b -> c) ->
     Comb CombSelectable repr c
-instance CombSelectable repr => Trans (Comb CombSelectable repr) repr where
-  trans = \case
-    Branch lr l r -> branch (trans lr) (trans l) (trans r)
+instance CombSelectable repr => Derivable (Comb CombSelectable repr) where
+  derive = \case
+    Branch lr l r -> branch (derive lr) (derive l) (derive r)
 instance
   ( CombApplicable repr
   , CombAlternable repr
index 57a3cd3659cf9903a4a2b6c1577bb61fbe20b9d1..a9d8a91674e2a8239227bab573ccb0c12af79d5d 100644 (file)
@@ -23,8 +23,8 @@ import qualified Language.Haskell.TH.Show as TH
 
 import Symantic.Typed.Data
 import Symantic.Typed.Lang
-import Symantic.Typed.Optim
-import Symantic.Typed.Trans
+import Symantic.Typed.Optimize
+import Symantic.Typed.Derive
 
 type Production = Product
   (SomeData Identity)
@@ -49,10 +49,10 @@ prod x = production x [||x||]
 
 {-# INLINE runValue #-}
 runValue :: Production a -> a
-runValue x = runIdentity (trans x)
+runValue (Pair v _c) = runIdentity (derive v)
 {-# INLINE runCode #-}
 runCode :: Production a -> TH.CodeQ a
-runCode = trans
+runCode (Pair _v c) = derive c
 
 -- Missing instances in 'Language.Haskell.TH',
 -- needed for 'prodCon'.
@@ -72,16 +72,11 @@ prodCon name = do
       [| production $(return (TH.ConE n))
            (TH.unsafeCodeCoerce (return (TH.ConE $(TH.lift n)))) |]
 
-instance Trans Production Identity where
-  trans (Pair (SomeData v) _c) = trans v
-instance Trans Production TH.CodeQ where
-  trans (Pair _v (SomeData c)) = trans c
-
 instance Show (SomeData TH.CodeQ a) where
-  -- The 'Trans' constraint contained in 'SomeData'
+  -- The 'Derivable' constraint contained in 'SomeData'
   -- is 'TH.CodeQ', hence 'Symantic.Typed.View' cannot be used here.
   -- Fortunately 'TH.showCode' can be implemented.
-  showsPrec p = showString Fun.. TH.showCode p Fun.. trans
+  showsPrec p = showString Fun.. TH.showCode p Fun.. derive
 
 instance (Abstractable f, Abstractable g) => Abstractable (Product f g) where
   -- Those 'undefined' are not unreachables by 'f'
index da175cf8d701fe702c519b2f6c701f7c9d5e3ab6..ef88c372539d8fad34b298906e92c0e558c125f5 100644 (file)
@@ -14,7 +14,7 @@ import qualified Data.HashMap.Strict as HM
 import qualified Data.List as List
 import qualified Data.Tree as Tree
 
-import Symantic.Typed.Letable
+import Symantic.Typed.ObserveSharing
 import Symantic.Parser.Grammar.Combinators
 import qualified Symantic.Parser.Grammar.Production as Prod
 
index 86fb0a3b0531bc5df1ab91475bf974eb83ee75f0..bf1021a22effcca0bc458fa9e7a22b3736c23c43 100644 (file)
@@ -15,9 +15,9 @@ import qualified Data.List as List
 import qualified Data.Text.Lazy as TL
 import qualified Data.Text.Lazy.Builder as TLB
 
-import Symantic.Typed.Letable
+import Symantic.Typed.ObserveSharing
+import Symantic.Typed.Fixity
 import Symantic.Parser.Grammar.Combinators
-import Symantic.Parser.Grammar.Fixity
 
 -- * Type 'WriteGrammar'
 newtype WriteGrammar (showName::Bool) a = WriteGrammar { unWriteGrammar ::
index 798cabbaf8b11a9589816484e92e5a84f140163d..bfe106d6650dba2a6a0de0a2380dfe620e44e8d4 100644 (file)
@@ -45,20 +45,20 @@ import qualified Data.Set.Internal as Set_
 import qualified Language.Haskell.TH as TH
 import qualified Language.Haskell.TH.Syntax as TH
 
-import Symantic.Typed.Letable
-import Symantic.Typed.Trans
+import Symantic.Typed.Derive
+import Symantic.Typed.ObserveSharing
 import Symantic.Parser.Grammar.Combinators (Exception(..), Failure(..), SomeFailure(..), inputTokenProxy)
 import Symantic.Parser.Machine.Input
 import Symantic.Parser.Machine.Instructions
 import qualified Language.Haskell.TH.HideName as TH
 import qualified Symantic.Typed.Lang as Prod
-import qualified Symantic.Typed.Optim as Prod
+import qualified Symantic.Typed.Optimize as Prod
 
 --import Debug.Trace
 
 -- | Convenient utility to generate some final 'TH.CodeQ'.
 genCode :: Splice a -> CodeQ a
-genCode = trans . Prod.normalOrderReduction
+genCode = derive . Prod.normalOrderReduction
 
 -- * Type 'Gen'
 -- | Generate the 'CodeQ' parsing the input.
index f2dec46b887f64e73de499c35ae9c931bda719f8..fb98a75d79660922d61ef1b321423eeaae8603ca 100644 (file)
@@ -17,10 +17,10 @@ import Type.Reflection (Typeable, typeRep, eqTypeRep, (:~~:)(..))
 import qualified Data.Functor as Functor
 import qualified Language.Haskell.TH as TH
 
+import Symantic.Typed.Derive
 import Symantic.Parser.Grammar
 import Symantic.Parser.Machine.Input
 import Symantic.Parser.Machine.Instructions
-import Symantic.Typed.Trans
 
 -- * Data family 'Instr'
 -- | 'Instr'uctions of the 'Machine'.
@@ -28,6 +28,7 @@ import Symantic.Typed.Trans
 data family Instr
   (instr :: ReprInstr -> Constraint)
   :: ReprInstr -> ReprInstr
+type instance Derived (Instr instr repr inp vs) = repr inp vs
 
 -- | Convenient utility to pattern-match a 'SomeInstr'.
 pattern Instr :: Typeable comb =>
@@ -49,13 +50,14 @@ pattern Instr x <- (unSomeInstr -> Just x)
 -- this also give a more undestandable code.
 data SomeInstr repr inp vs a =
   forall instr.
-  ( Trans (Instr instr repr inp vs) (repr inp vs)
+  ( Derivable (Instr instr repr inp vs)
   , Typeable instr
   ) =>
   SomeInstr (Instr instr repr inp vs a)
 
-instance Trans (SomeInstr repr inp vs) (repr inp vs) where
-  trans (SomeInstr x) = trans x
+type instance Derived (SomeInstr repr inp vs) = repr inp vs
+instance Derivable (SomeInstr repr inp vs) where
+  derive (SomeInstr x) = derive x
 
 -- | @(unSomeInstr i :: 'Maybe' ('Instr' comb repr inp vs a))@
 -- extract the data-constructor from the given 'SomeInstr'
@@ -86,12 +88,12 @@ data instance Instr InstrValuable repr inp vs a where
   SwapValue ::
     SomeInstr repr inp (x ': y ': vs) a ->
     Instr InstrValuable repr inp (y ': x ': vs) a
-instance InstrValuable repr => Trans (Instr InstrValuable repr inp vs) (repr inp vs) where
-  trans = \case
-    PushValue x k -> pushValue x (trans k)
-    PopValue k -> popValue (trans k)
-    Lift2Value f k -> lift2Value f (trans k)
-    SwapValue k -> swapValue (trans k)
+instance InstrValuable repr => Derivable (Instr InstrValuable repr inp vs) where
+  derive = \case
+    PushValue x k -> pushValue x (derive k)
+    PopValue k -> popValue (derive k)
+    Lift2Value f k -> lift2Value f (derive k)
+    SwapValue k -> swapValue (derive k)
 instance InstrValuable repr => InstrValuable (SomeInstr repr) where
   -- 'PopValue' after a 'PushValue' is a no-op.
   pushValue _v (Instr (PopValue i)) = i
@@ -117,12 +119,12 @@ data instance Instr InstrExceptionable repr inp vs a where
     SomeInstr repr inp vs ret ->
     SomeInstr repr inp (Cursor inp ': vs) ret ->
     Instr InstrExceptionable repr inp vs ret
-instance InstrExceptionable repr => Trans (Instr InstrExceptionable repr inp vs) (repr inp vs) where
-  trans = \case
+instance InstrExceptionable repr => Derivable (Instr InstrExceptionable repr inp vs) where
+  derive = \case
     Raise exn -> raise exn
     Fail fs -> fail fs
-    Commit exn k -> commit exn (trans k)
-    Catch exn l r -> catch exn (trans l) (trans r)
+    Commit exn k -> commit exn (derive k)
+    Catch exn l r -> catch exn (derive l) (derive r)
 instance InstrExceptionable repr => InstrExceptionable (SomeInstr repr) where
   raise = SomeInstr . Raise
   fail = SomeInstr . Fail
@@ -140,10 +142,10 @@ data instance Instr InstrBranchable repr inp vs a where
     [SomeInstr repr inp vs a] ->
     SomeInstr repr inp vs a ->
     Instr InstrBranchable repr inp (v ': vs) a
-instance InstrBranchable repr => Trans (Instr InstrBranchable repr inp vs) (repr inp vs) where
-  trans = \case
-    CaseBranch l r -> caseBranch (trans l) (trans r)
-    ChoicesBranch ps bs d -> choicesBranch ps (trans Functor.<$> bs) (trans d)
+instance InstrBranchable repr => Derivable (Instr InstrBranchable repr inp vs) where
+  derive = \case
+    CaseBranch l r -> caseBranch (derive l) (derive r)
+    ChoicesBranch ps bs d -> choicesBranch ps (derive Functor.<$> bs) (derive d)
 instance InstrBranchable repr => InstrBranchable (SomeInstr repr) where
   caseBranch l = SomeInstr . CaseBranch l
   choicesBranch ps bs = SomeInstr . ChoicesBranch ps bs
@@ -163,11 +165,11 @@ data instance Instr InstrCallable repr inp vs a where
   Jump ::
     LetName a ->
     Instr InstrCallable repr inp '[] a
-instance InstrCallable repr => Trans (Instr InstrCallable repr inp vs) (repr inp vs) where
-  trans = \case
-    DefLet subs k -> defLet ((\(SomeLet sub) -> SomeLet (trans sub)) Functor.<$> subs) (trans k)
+instance InstrCallable repr => Derivable (Instr InstrCallable repr inp vs) where
+  derive = \case
+    DefLet subs k -> defLet ((\(SomeLet sub) -> SomeLet (derive sub)) Functor.<$> subs) (derive k)
     Jump n -> jump n
-    Call n k -> call n (trans k)
+    Call n k -> call n (derive k)
     Ret -> ret
 instance InstrCallable repr => InstrCallable (SomeInstr repr) where
   defLet subs = SomeInstr . DefLet subs
@@ -185,9 +187,9 @@ data instance Instr InstrJoinable repr inp vs a where
   RefJoin ::
     LetName v ->
     Instr InstrJoinable repr inp (v ': vs) a
-instance InstrJoinable repr => Trans (Instr InstrJoinable repr inp vs) (repr inp vs) where
-  trans = \case
-    DefJoin n sub k -> defJoin n (trans sub) (trans k)
+instance InstrJoinable repr => Derivable (Instr InstrJoinable repr inp vs) where
+  derive = \case
+    DefJoin n sub k -> defJoin n (derive sub) (derive k)
     RefJoin n -> refJoin n
 instance InstrJoinable repr => InstrJoinable (SomeInstr repr) where
   defJoin n sub = SomeInstr . DefJoin n sub
@@ -201,10 +203,10 @@ data instance Instr InstrInputable repr inp vs a where
   LoadInput ::
     SomeInstr repr inp vs a ->
     Instr InstrInputable repr inp (Cursor inp ': vs) a
-instance InstrInputable repr => Trans (Instr InstrInputable repr inp vs) (repr inp vs) where
-  trans = \case
-    PushInput k -> pushInput (trans k)
-    LoadInput k -> loadInput (trans k)
+instance InstrInputable repr => Derivable (Instr InstrInputable repr inp vs) where
+  derive = \case
+    PushInput k -> pushInput (derive k)
+    LoadInput k -> loadInput (derive k)
 instance InstrInputable repr => InstrInputable (SomeInstr repr) where
   pushInput = SomeInstr . PushInput
   loadInput = SomeInstr . LoadInput
@@ -218,9 +220,9 @@ data instance Instr (InstrReadable tok) repr inp vs a where
     Instr (InstrReadable tok) repr inp vs a
 instance
   ( InstrReadable tok repr, tok ~ InputToken inp ) =>
-  Trans (Instr (InstrReadable tok) repr inp vs) (repr inp vs) where
-  trans = \case
-    Read fs p k -> read fs p (trans k)
+  Derivable (Instr (InstrReadable tok) repr inp vs) where
+  derive = \case
+    Read fs p k -> read fs p (derive k)
 instance
   ( InstrReadable tok repr, Typeable tok ) =>
   InstrReadable tok (SomeInstr repr) where
index 014ea986e5eb1c4b7aac7dcf83d8298e2080f115..bcffef6c647c7970715bcdc6cac4f52ba3392b75 100644 (file)
@@ -26,11 +26,11 @@ import qualified Language.Haskell.TH as TH
 import qualified Language.Haskell.TH.Syntax as TH
 import qualified Symantic.Typed.Lang as Prod
 
+import Symantic.Typed.Derive
 import Symantic.Parser.Grammar
 import Symantic.Parser.Machine.Input
 import Symantic.Parser.Machine.Instructions
 import Symantic.Parser.Machine.Optimize
-import Symantic.Typed.Trans
 
 -- * Type 'Program'
 -- | A 'Program' is a tree of 'Instr'uctions,
@@ -52,7 +52,7 @@ optimizeMachine ::
   Machinable (InputToken inp) repr =>
   Program repr inp a ->
   IO (repr inp '[] a)
-optimizeMachine (Program f) = trans Functor.<$> f @'[] ret
+optimizeMachine (Program f) = derive Functor.<$> f @'[] ret
 
 -- * Class 'Machinable'
 -- | All the 'Instr'uctions.
@@ -82,17 +82,17 @@ instance
   , InstrReadable (InputToken inp) repr
   , Typeable (InputToken inp)
   ) =>
-  Trans (Comb CombAlternable (Program repr inp)) (Program repr inp) where
-  trans = \case
+  Derivable (Comb CombAlternable (Program repr inp)) where
+  derive = \case
     Alt ExceptionFailure
       (Comb (SatisfyOrFail _fs p :: Comb (CombSatisfiable (InputToken inp)) (Program repr inp) a))
       (Comb (Failure sf)) ->
       satisfyOrFail (Set.singleton sf) p
-    Alt exn x y -> alt exn (trans x) (trans y)
+    Alt exn x y -> alt exn (derive x) (derive y)
     Empty -> empty
     Failure sf -> failure sf
     Throw exn -> throw exn
-    Try x -> try (trans x)
+    Try x -> try (derive x)
 
 instance
   ( Cursorable (Cursor inp)
index 6079d25e3530d0f2d711db947f28ae7f66c6c2b3..2e2e42067269ceb5b348845806d8fe7e9fb810b9 100644 (file)
@@ -22,7 +22,7 @@ import Prelude (error)
 
 import Symantic.Parser.Grammar.ObserveSharing (ShowLetName(..))
 import Symantic.Parser.Machine.Instructions
-import Symantic.Typed.Letable (SomeLet(..))
+import Symantic.Typed.ObserveSharing (SomeLet(..))
 import Symantic.Parser.Machine.Generate
 
 -- * Type 'ViewMachine'
diff --git a/src/Symantic/Typed/Data.hs b/src/Symantic/Typed/Data.hs
deleted file mode 100644 (file)
index cc844c3..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-{-# LANGUAGE ConstraintKinds #-}
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE KindSignatures #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE PatternSynonyms #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TypeApplications #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE ViewPatterns #-}
-module Symantic.Typed.Data where
-
-import Data.Kind (Constraint, Type)
-import Type.Reflection (Typeable, (:~~:)(..), eqTypeRep, typeRep)
-import Data.Bool (Bool)
-import Data.Either (Either)
-import Data.Maybe (Maybe)
-import qualified Data.Eq as Eq
-import qualified Data.Maybe as Maybe
-import qualified Data.Function as Fun
-
-import Symantic.Typed.Lang
-import Symantic.Typed.Trans
-
-data SomeData repr a =
-  forall able.
-  ( Trans (Data able repr) repr
-  , Typeable able
-  ) => SomeData (Data able repr a)
-
-instance Trans (SomeData repr) repr where
-  trans (SomeData x) = trans x
-
-type TypedRepr = Type -> Type
-
--- TODO: neither data families nor data instances
--- can have phantom roles with GHC-9's RoleAnnotations,
--- hence 'Data.Coerce.coerce' cannot be used on them for now.
--- https://gitlab.haskell.org/ghc/ghc/-/issues/8177
--- https://gitlab.haskell.org/ghc/ghc/-/wikis/roles#proposal-roles-for-type-families
--- Would be useful for @Trans (Data able repr) (Data able repr')@ instances.
-data family Data
-  (able :: TypedRepr -> Constraint)
-  :: TypedRepr -> TypedRepr
---instance Trans (Data able repr) (Data able repr) where
---  trans = Fun.id
-
--- | Convenient utility to pattern-match a 'SomeData'.
-pattern Data :: Typeable able => Data able repr a -> SomeData repr a
-pattern Data x <- (unSomeData -> Maybe.Just x)
-
--- | @(unSomeData c :: 'Maybe' ('Data' able repr a))@
--- extract the data-constructor from the given 'SomeData'
--- iif. it belongs to the @('Data' able repr a)@ data-instance.
-unSomeData ::
-  forall able repr a.
-  Typeable able =>
-  SomeData repr a -> Maybe (Data able repr a)
-unSomeData (SomeData (c::Data c repr a)) =
-  case typeRep @able `eqTypeRep` typeRep @c of
-    Maybe.Just HRefl -> Maybe.Just c
-    Maybe.Nothing -> Maybe.Nothing
-
--- Abstractable
-data instance Data Abstractable repr a where
-  (:@) :: SomeData repr (a->b) -> SomeData repr a -> Data Abstractable repr b
-  Lam :: (SomeData repr a -> SomeData repr b) -> Data Abstractable repr (a->b)
-  Lam1 :: (SomeData repr a -> SomeData repr b) -> Data Abstractable repr (a->b)
-  Var :: repr a -> Data Abstractable repr a
-  -- FIXME: add constructors
-instance
-  ( Abstractable repr
-  --, Trans (SomeData repr) repr
-  --, Trans repr (SomeData repr)
-  ) => Trans (Data Abstractable repr) repr where
-  trans = \case
-    f :@ x -> trans f .@ trans x
-    Lam f -> lam (\x -> trans (f (SomeData (Var x))))
-    Lam1 f -> lam1 (\x -> trans (f (SomeData (Var x))))
-    Var x -> var x
-instance
-  ( Abstractable repr
-  --, Trans (SomeData repr) repr
-  --, Trans repr (SomeData repr)
-  ) => Abstractable (SomeData repr) where
-  f .@ x = SomeData (f :@ x)
-  lam f = SomeData (Lam f)
-  lam1 f = SomeData (Lam1 f)
-  var = Fun.id
-  ($) = lam1 (\f -> lam1 (\x -> f .@ x))
-  (.) = lam1 (\f -> lam1 (\g -> lam1 (\x -> f .@ (g .@ x))))
-  const = lam1 (\x -> lam1 (\_y -> x))
-  flip = lam1 (\f -> lam1 (\x -> lam1 (\y -> f .@ y .@ x)))
-  id = lam1 (\x -> x)
-
-{-
-instance
-  ( Abstractable repr
-  ) =>
-  Abstractable (Data Abstractable repr) where
-  var = Var Fun.. SomeData
-  f .@ x = SomeData f :@ SomeData x
-  lam f = Lam (SomeData Fun.. f Fun.. Var)
-  lam1 f = Lam1 (SomeData Fun.. f Fun.. Var)
-  ($) = lam1 (\f -> lam1 (\x -> f .@ x))
-  (.) = lam1 (\f -> lam1 (\g -> lam1 (\x -> f .@ (g .@ x))))
-  const = lam1 (\x -> lam1 (\_y -> x))
-  flip = lam1 (\f -> lam1 (\x -> lam1 (\y -> f .@ y .@ x)))
-  id = lam1 (\x -> x)
--}
-{-
-instance Bottomable repr => Morph (SomeData repr) (SomeData Unit) where
-  morph (SomeData x) = morph x
-instance Bottomable repr => Morph (SomeData Unit) (SomeData repr) where
-  morph (SomeData x) = morph x
-instance Abstractable Unit where
-  (.@) _f _x = Unit
-  lam _f = Unit
-  lam1 _f = Unit
-  ($) = Unit
-  (.) = Unit
-  const = Unit
-  flip = Unit
-  id = Unit
-instance Abstractable (Data Abstractable Unit) where
-  f .@ x = SomeData f :@ SomeData x
-  lam f = Lam (\(SomeData x) -> SomeData (f (trans x)))
-  lam1 f = Lam1 (\(SomeData x) -> SomeData (f (trans x)))
-  ($) = ($)
-  (.) = (.)
-  const = const
-  flip = flip
-  id = id
--}
-
--- Anythingable
-data instance Data Anythingable repr a where
-  Anything :: repr a -> Data Anythingable repr a
-instance
-  ( Anythingable repr
-  ) =>
-  Trans (Data Anythingable repr) repr where
-  trans = \case
-    Anything x -> anything x
-instance Anythingable (SomeData repr)
-instance Anythingable (Data Anythingable repr)
-
--- Bottomable
-class Bottomable repr where
-  bottom :: repr a
-data instance Data Bottomable repr a where
-  Bottom :: Data Bottomable repr a
-instance Bottomable repr => Trans (Data Bottomable repr) repr where
-  trans Bottom{} = bottom
-
--- Constantable
-data instance Data (Constantable c) repr a where
-  Constant :: {-Typeable c =>-} c -> Data (Constantable c) repr c
-instance Constantable c repr => Trans (Data (Constantable c) repr) repr where
-  trans = \case
-    Constant x -> constant x
-instance
-  ( Constantable c repr
-  , Typeable c
-  ) => Constantable c (SomeData repr) where
-  constant c = SomeData (Constant c)
-instance {-Typeable c =>-} Constantable c (Data (Constantable c) repr) where
-  constant = Constant
-
--- Eitherable
-data instance Data Eitherable repr a where
-  Left :: Data Eitherable repr (l -> Either l r)
-  Right :: Data Eitherable repr (r -> Either l r)
-instance Eitherable repr => Trans (Data Eitherable repr) repr where
-  trans = \case
-    Left -> left
-    Right -> right
-instance
-  ( Eitherable repr
-  ) => Eitherable (SomeData repr) where
-  left = SomeData Left
-  right = SomeData Right
-instance Eitherable (Data Eitherable repr) where
-  left = Left
-  right = Right
-
--- Equalable
-data instance Data Equalable repr a where
-  Equal :: Eq.Eq a => Data Equalable repr (a -> a -> Bool)
-instance Equalable repr => Trans (Data Equalable repr) repr where
-  trans = \case
-    Equal -> equal
-instance
-  ( Equalable repr
-  ) => Equalable (SomeData repr) where
-  equal = SomeData Equal
-instance Equalable (Data Equalable repr) where
-  equal = Equal
-
--- IfThenElseable
-data instance Data IfThenElseable repr a where
-  IfThenElse ::
-    SomeData repr Bool ->
-    SomeData repr a ->
-    SomeData repr a ->
-    Data IfThenElseable repr a
-instance IfThenElseable repr => Trans (Data IfThenElseable repr) repr where
-  trans = \case
-    IfThenElse test ok ko -> ifThenElse (trans test) (trans ok) (trans ko)
-instance
-  ( IfThenElseable repr
-  ) => IfThenElseable (SomeData repr) where
-  ifThenElse test ok ko = SomeData (IfThenElse test ok ko)
-instance IfThenElseable repr => IfThenElseable (Data IfThenElseable repr) where
-  ifThenElse test ok ko = IfThenElse (SomeData test) (SomeData ok) (SomeData ko)
-
--- Listable
-data instance Data Listable repr a where
-  Cons :: Data Listable repr (a -> [a] -> [a])
-  Nil :: Data Listable repr [a]
-infixr 4 `Cons`
-instance Listable repr => Trans (Data Listable repr) repr where
-  trans = \case
-    Cons -> cons
-    Nil -> nil
-instance
-  ( Listable repr
-  ) => Listable (SomeData repr) where
-  cons = SomeData Cons
-  nil = SomeData Nil
-instance Listable (Data Listable repr) where
-  cons = Cons
-  nil = Nil
-
--- Maybeable
-data instance Data Maybeable repr a where
-  Nothing :: Data Maybeable repr (Maybe a)
-  Just :: Data Maybeable repr (a -> Maybe a)
-instance Maybeable repr => Trans (Data Maybeable repr) repr where
-  trans = \case
-    Nothing -> nothing
-    Just -> just
-instance
-  ( Maybeable repr
-  ) => Maybeable (SomeData repr) where
-  nothing = SomeData Nothing
-  just = SomeData Just
-instance Maybeable (Data Maybeable repr) where
-  nothing = Nothing
-  just = Just
diff --git a/src/Symantic/Typed/Lang.hs b/src/Symantic/Typed/Lang.hs
deleted file mode 100644 (file)
index e0b8a56..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-{-# LANGUAGE ConstraintKinds #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE DefaultSignatures #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE NoMonomorphismRestriction #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeApplications #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE NoImplicitPrelude #-}
-module Symantic.Typed.Lang where
-
-import Data.Char (Char)
-import Data.Bool (Bool(..))
-import Data.Either (Either(..))
-import Data.Eq (Eq)
-import Data.Maybe (Maybe(..))
-import qualified Data.Function as Fun
-
-import Symantic.Typed.Trans
-
-class Abstractable repr where
-  -- | Application, aka. unabstract.
-  (.@) :: repr (a->b) -> repr a -> repr b; infixl 9 .@
-  -- | Lambda term abstraction, in HOAS (Higher-Order Abstract Syntax) style.
-  lam :: (repr a -> repr b) -> repr (a->b)
-  -- | Like 'lam' but whose argument is used only once,
-  -- hence safe to beta-reduce (inline) without duplicating work.
-  lam1 :: (repr a -> repr b) -> repr (a->b)
-  const :: repr (a -> b -> a)
-  flip :: repr ((a -> b -> c) -> b -> a -> c)
-  id :: repr (a->a)
-  (.) :: repr ((b->c) -> (a->b) -> a -> c); infixr 9 .
-  ($) :: repr ((a->b) -> a -> b); infixr 0 $
-  var :: repr a -> repr a
-  default (.@) ::
-    Liftable2 repr => Abstractable (Unlifted repr) =>
-    repr (a->b) -> repr a -> repr b
-  default lam ::
-    Liftable repr => Unliftable repr => Abstractable (Unlifted repr) =>
-    (repr a -> repr b) -> repr (a->b)
-  default lam1 ::
-    Liftable repr => Unliftable repr => Abstractable (Unlifted repr) =>
-    (repr a -> repr b) -> repr (a->b)
-  default const ::
-    Liftable repr => Abstractable (Unlifted repr) =>
-    repr (a -> b -> a)
-  default flip ::
-    Liftable repr => Abstractable (Unlifted repr) =>
-    repr ((a -> b -> c) -> b -> a -> c)
-  default id ::
-    Liftable repr => Abstractable (Unlifted repr) =>
-    repr (a->a)
-  default (.) ::
-    Liftable repr => Abstractable (Unlifted repr) =>
-    repr ((b->c) -> (a->b) -> a -> c)
-  default ($) ::
-    Liftable repr => Abstractable (Unlifted repr) =>
-    repr ((a->b) -> a -> b)
-  default var ::
-    Liftable1 repr => Abstractable (Unlifted repr) =>
-    repr a -> repr a
-  (.@) = lift2 (.@)
-  lam f = lift (lam (trans Fun.. f Fun.. trans))
-  lam1 f = lift (lam1 (trans Fun.. f Fun.. trans))
-  const = lift const
-  flip = lift flip
-  id = lift id
-  (.) = lift (.)
-  ($) = lift ($)
-  var = lift1 var
-class Anythingable repr where
-  anything :: repr a -> repr a
-  anything = Fun.id
-class Constantable c repr where
-  constant :: c -> repr c
-  default constant ::
-    Liftable repr => Constantable c (Unlifted repr) =>
-    c -> repr c
-  constant = lift Fun.. constant
-bool :: Constantable Bool repr => Bool -> repr Bool
-bool = constant @Bool
-char :: Constantable Char repr => Char -> repr Char
-char = constant @Char
-unit :: Constantable () repr => repr ()
-unit = constant @() ()
-class Eitherable repr where
-  left :: repr (l -> Either l r)
-  right :: repr (r -> Either l r)
-  default left ::
-    Liftable repr => Eitherable (Unlifted repr) =>
-    repr (l -> Either l r)
-  default right ::
-    Liftable repr => Eitherable (Unlifted repr) =>
-    repr (r -> Either l r)
-  left = lift left
-  right = lift right
-class Equalable repr where
-  equal :: Eq a => repr (a -> a -> Bool)
-  default equal ::
-    Liftable repr => Equalable (Unlifted repr) =>
-    Eq a => repr (a -> a -> Bool)
-  equal = lift equal
-infix 4 `equal`, ==
-(==) :: (Abstractable repr, Equalable repr, Eq a) => repr (a -> a -> Bool)
-(==) = lam (\x -> lam (\y -> equal .@ x .@ y))
-class IfThenElseable repr where
-  ifThenElse :: repr Bool -> repr a -> repr a -> repr a
-  default ifThenElse ::
-    Liftable3 repr => IfThenElseable (Unlifted repr) =>
-    repr Bool -> repr a -> repr a -> repr a
-  ifThenElse = lift3 ifThenElse
-class Listable repr where
-  cons :: repr (a -> [a] -> [a])
-  nil :: repr [a]
-  default cons ::
-    Liftable repr => Listable (Unlifted repr) =>
-    repr (a -> [a] -> [a])
-  default nil ::
-    Liftable repr => Listable (Unlifted repr) =>
-    repr [a]
-  cons = lift cons
-  nil = lift nil
-class Maybeable repr where
-  nothing :: repr (Maybe a)
-  just :: repr (a -> Maybe a)
-  default nothing ::
-    Liftable repr => Maybeable (Unlifted repr) =>
-    repr (Maybe a)
-  default just ::
-    Liftable repr => Maybeable (Unlifted repr) =>
-    repr (a -> Maybe a)
-  nothing = lift nothing
-  just = lift just
diff --git a/src/Symantic/Typed/Letable.hs b/src/Symantic/Typed/Letable.hs
deleted file mode 100644 (file)
index 0abaee7..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-{-# LANGUAGE AllowAmbiguousTypes #-} -- For ShowLetName
-{-# LANGUAGE DefaultSignatures #-}
-{-# LANGUAGE ExistentialQuantification #-} -- For SharingName
--- {-# LANGUAGE MagicHash #-} -- For unsafeCoerce#
-module Symantic.Typed.Letable where
-
-import Control.Applicative (Applicative(..))
-import Control.Monad (Monad(..))
-import Data.Bool (Bool(..))
-import Data.Eq (Eq(..))
-import Data.Foldable (foldMap)
-import Data.Function (($), (.))
-import Data.Functor ((<$>))
-import Data.Functor.Compose (Compose(..))
-import Data.HashMap.Strict (HashMap)
-import Data.HashSet (HashSet)
-import Data.Hashable (Hashable, hashWithSalt, hash)
-import Data.Int (Int)
-import Data.Maybe (Maybe(..), isNothing)
-import Data.Monoid (Monoid(..))
-import Data.Ord (Ord(..))
-import Data.String (String)
--- import GHC.Exts (Int(..))
--- import GHC.Prim (unsafeCoerce#)
-import GHC.StableName (StableName(..), makeStableName, hashStableName, eqStableName)
--- import Numeric (showHex)
-import Prelude ((+), error)
-import System.IO (IO)
-import System.IO.Unsafe (unsafePerformIO)
-import Text.Show (Show(..))
-import qualified Control.Monad.Trans.Class as MT
-import qualified Control.Monad.Trans.Reader as MT
-import qualified Control.Monad.Trans.State as MT
-import qualified Control.Monad.Trans.Writer as MT
-import qualified Data.HashMap.Strict as HM
-import qualified Data.HashSet as HS
-
-import Symantic.Typed.Trans
-
---import Debug.Trace (trace)
-
--- * Class 'Letable'
--- | This class is not for end-users like usual symantic operators,
--- here 'shareable' and 'ref' are introduced by 'observeSharing'.
-class Letable letName repr where
-  -- | @('ref' isRec letName)@ is a reference to @(letName)@.
-  -- @(isRec)@ is 'True' iif. this 'ref'erence is recursive,
-  -- ie. is reachable within its 'def'inition.
-  ref :: Bool -> letName -> repr a
-  default ref ::
-    Liftable repr => Letable letName (Unlifted repr) =>
-    Bool -> letName -> repr a
-  ref isRec n = lift (ref isRec n)
-
-  -- | @('shareable' letName x)@ let-binds @(letName)@ to be equal to @(x)@.
-  shareable :: letName -> repr a -> repr a
-  default shareable ::
-    Liftable1 repr => Letable letName (Unlifted repr) =>
-    letName -> repr a -> repr a
-  shareable n = lift1 (shareable n)
-
--- * Class 'MakeLetName'
-class MakeLetName letName where
-  makeLetName :: SharingName -> IO letName
-
--- ** Type 'ShowLetName'
--- | Useful on golden unit tests because 'StableName'
--- change often when changing unrelated source code
--- or even changing basic GHC or executable flags.
-class ShowLetName (showName::Bool) letName where
-  showLetName :: letName -> String
--- | Like 'Show'.
-instance Show letName => ShowLetName 'True letName where
-  showLetName = show
--- | Always return @"<hidden>"@,
-instance ShowLetName 'False letName where
-  showLetName _p = "<hidden>"
-
--- * Type 'SharingName'
--- | 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.
-data SharingName = forall a. SharingName (StableName a)
--- | @('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](https://gitlab.haskell.org/ghc/ghc/-/issues/2916).
-makeSharingName :: a -> SharingName
-makeSharingName !x = SharingName $ unsafePerformIO $ makeStableName x
-
-instance Eq SharingName where
-  SharingName x == SharingName y = eqStableName x y
-instance Hashable SharingName where
-  hash (SharingName n) = hashStableName n
-  hashWithSalt salt (SharingName n) = hashWithSalt salt n
-{-
-instance Show SharingName where
-  showsPrec _ (SharingName n) = showHex (I# (unsafeCoerce# n))
--}
-
--- * Type 'ObserveSharing'
-newtype ObserveSharing letName repr a = ObserveSharing { unObserveSharing ::
-  MT.ReaderT (HashSet SharingName)
-             (MT.State (ObserveSharingState letName))
-             (FinalizeSharing letName repr a) }
-
--- | Interpreter detecting some (Haskell embedded) @let@ definitions used at
--- least once and/or recursively, in order to replace them
--- with the 'def' and 'ref' combinators.
--- See [Type-safe observable sharing in Haskell](https://doi.org/10.1145/1596638.1596653)
---
--- Beware not to apply 'observeSharing' more than once on the same term
--- otherwise some 'shareable' introduced by the first call
--- would be removed by the second call.
-observeSharing ::
-  Eq letName =>
-  Hashable letName =>
-  Show letName =>
-  ObserveSharing letName repr a ->
-  WithSharing letName repr a
-observeSharing (ObserveSharing m) =
-  let (fs, st) = MT.runReaderT m mempty `MT.runState`
-        ObserveSharingState
-          { oss_refs = HM.empty
-          , oss_recs = HS.empty
-          } in
-  let refs = HS.fromList $
-        (`foldMap` oss_refs st) $ (\(letName, refCount) ->
-          if refCount > 0 then [letName] else []) in
-  --trace (show refs) $
-  MT.runWriter $
-    (`MT.runReaderT` refs) $
-      unFinalizeSharing fs
-
--- ** Type 'SomeLet'
-data SomeLet repr = forall a. SomeLet (repr a)
-
--- ** Type 'WithSharing'
-type WithSharing letName repr a =
-  (repr a, HM.HashMap letName (SomeLet repr))
-{-
--- * Type 'WithSharing'
-data WithSharing letName repr a = WithSharing
-  { lets :: HM.HashMap letName (SomeLet repr)
-  , body :: repr a
-  }
-mapWithSharing ::
-  (forall v. repr v -> repr v) ->
-  WithSharing letName repr a ->
-  WithSharing letName repr a
-mapWithSharing f ws = WithSharing
-  { lets = (\(SomeLet repr) -> SomeLet (f repr)) <$> lets ws
-  , body = f (body ws)
-  }
--}
-
--- ** Type 'ObserveSharingState'
-data ObserveSharingState letName = ObserveSharingState
-  { oss_refs :: HashMap SharingName (letName, Int)
-  , oss_recs :: HashSet SharingName
-    -- ^ TODO: unused so far, will it be useful somewhere at a later stage?
-  }
-
-observeSharingNode ::
-  Eq letName =>
-  Hashable letName =>
-  Show letName =>
-  Letable letName repr =>
-  MakeLetName letName =>
-  ObserveSharing letName repr a ->
-  ObserveSharing letName repr a
-observeSharingNode (ObserveSharing m) = ObserveSharing $ do
-  let nodeName = makeSharingName m
-  st <- MT.lift MT.get
-  ((letName, before), preds) <- getCompose $ HM.alterF (\before ->
-    Compose $ case before of
-      Nothing -> do
-        let letName = unsafePerformIO $ makeLetName nodeName
-        return ((letName, before), Just (letName, 0))
-      Just (letName, refCount) -> do
-        return ((letName, before), Just (letName, refCount + 1))
-    ) nodeName (oss_refs st)
-  parentNames <- MT.ask
-  if nodeName `HS.member` parentNames
-  then do
-    MT.lift $ MT.put st
-      { oss_refs = preds
-      , oss_recs = HS.insert nodeName (oss_recs st)
-      }
-    return $ ref True letName
-  else do
-    MT.lift $ MT.put st{ oss_refs = preds }
-    if isNothing before
-      then MT.local (HS.insert nodeName) (shareable letName <$> m)
-      else return $ ref False letName
-
-type instance Unlifted (ObserveSharing letName repr) = FinalizeSharing letName repr
-instance
-  ( Letable letName repr
-  , MakeLetName letName
-  , Eq letName
-  , Hashable letName
-  , Show letName
-  ) => Trans (FinalizeSharing letName repr) (ObserveSharing letName repr) where
-  trans = observeSharingNode . ObserveSharing . return
-instance
-  ( Letable letName repr
-  , MakeLetName letName
-  , Eq letName
-  , Hashable letName
-  , Show letName
-  ) => Trans1 (FinalizeSharing letName repr) (ObserveSharing letName repr) where
-  trans1 f x = observeSharingNode $ ObserveSharing $
-    f <$> unObserveSharing x
-instance
-  ( Letable letName repr
-  , MakeLetName letName
-  , Eq letName
-  , Hashable letName
-  , Show letName
-  ) => Trans2 (FinalizeSharing letName repr) (ObserveSharing letName repr) where
-  trans2 f x y = observeSharingNode $ ObserveSharing $
-    f <$> unObserveSharing x
-      <*> unObserveSharing y
-instance
-  ( Letable letName repr
-  , MakeLetName letName
-  , Eq letName
-  , Hashable letName
-  , Show letName
-  ) => Trans3 (FinalizeSharing letName repr) (ObserveSharing letName repr) where
-  trans3 f x y z = observeSharingNode $ ObserveSharing $
-    f <$> unObserveSharing x
-      <*> unObserveSharing y
-      <*> unObserveSharing z
-instance Letable letName (ObserveSharing letName repr) where
-  shareable = error "[BUG]: observeSharing MUST NOT be applied twice"
-  ref = error "[BUG]: observeSharing MUST NOT be applied twice"
-instance Letsable letName (ObserveSharing letName repr) where
-  lets = error "[BUG]: observeSharing MUST NOT be applied twice"
-
--- * Type 'FinalizeSharing'
--- | Remove 'shareable' when non-recursive or unused
--- or replace it by 'ref', moving 'def' a top.
-newtype FinalizeSharing letName repr a = FinalizeSharing { unFinalizeSharing ::
-  MT.ReaderT (HS.HashSet letName)
-    (MT.Writer (LetBindings letName repr))
-      (repr a) }
-
--- ** Type 'LetBindings'
-type LetBindings letName repr = HM.HashMap letName (SomeLet repr)
-
-type instance Unlifted (FinalizeSharing _letName repr) = repr
-instance
-  ( Eq letName
-  , Hashable letName
-  ) => Trans repr (FinalizeSharing letName repr) where
-  trans = FinalizeSharing . pure
-instance
-  ( Eq letName
-  , Hashable letName
-  ) => Trans1 repr (FinalizeSharing letName repr) where
-  trans1 f x = FinalizeSharing $ f <$> unFinalizeSharing x
-instance
-  ( Eq letName
-  , Hashable letName
-  ) => Trans2 repr (FinalizeSharing letName repr) where
-  trans2 f x y = FinalizeSharing $
-    f <$> unFinalizeSharing x
-      <*> unFinalizeSharing y
-instance
-  ( Eq letName
-  , Hashable letName
-  ) => Trans3 repr (FinalizeSharing letName repr) where
-  trans3 f x y z = FinalizeSharing $
-    f <$> unFinalizeSharing x
-      <*> unFinalizeSharing y
-      <*> unFinalizeSharing z
-instance
-  ( Letable letName repr
-  , Eq letName
-  , Hashable letName
-  , Show letName
-  ) => Letable letName (FinalizeSharing letName repr) where
-  shareable name x = FinalizeSharing $ do
-    refs <- MT.ask
-    if name `HS.member` refs
-      -- This 'shareable' is 'ref'erenced, move it into the result,
-      -- to put it in scope even when some 'ref' to it exists outside of 'x'
-      -- (which can happen when a sub-expression is shared),
-      -- and replace it by a 'ref'.
-      then do
-        let (repr, defs) = MT.runWriter $ MT.runReaderT (unFinalizeSharing x) refs
-        MT.lift $ MT.tell $ HM.insert name (SomeLet repr) defs
-        return $ ref False name
-      -- Remove 'shareable'.
-      else
-        unFinalizeSharing x
-
--- * Class 'Letsable'
-class Letsable letName repr where
-  -- | @('lets' defs x)@ let-binds @(defs)@ in @(x)@.
-  lets :: LetBindings letName repr -> repr a -> repr a
-  default lets ::
-    Trans repr (Unlifted repr) =>
-    Liftable1 repr => Letsable letName (Unlifted repr) =>
-    LetBindings letName repr -> repr a -> repr a
-  lets defs = lift1 (lets ((\(SomeLet val) -> SomeLet (trans val)) <$> defs))
-{-
--- | Not used but can be written nonetheless.
-instance
-  ( Letsable letName repr
-  , Eq letName
-  , Hashable letName
-  , Show letName
-  ) => Letsable letName (FinalizeSharing letName repr) where
-  lets defs x = FinalizeSharing $ do
-    ds <- traverse (\(SomeLet v) -> do
-      r <- unFinalizeSharing v
-      return (SomeLet r)
-      ) defs
-    MT.lift $ MT.tell ds
-    unFinalizeSharing x
--}
diff --git a/src/Symantic/Typed/Optim.hs b/src/Symantic/Typed/Optim.hs
deleted file mode 100644 (file)
index d8d88fd..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-module Symantic.Typed.Optim where
-
-import Data.Bool (Bool)
-import qualified Data.Function as Fun
-import Symantic.Typed.Lang
-import Symantic.Typed.Data
-
--- | Beta-reduce the left-most outer-most lambda abstraction (aka. normal-order reduction),
--- but to avoid duplication of work, only those manually marked
--- as using their variable at most once.
---
--- DOC: Demonstrating Lambda Calculus Reduction, Peter Sestoft, 2001,
--- https://www.itu.dk/people/sestoft/papers/sestoft-lamreduce.pdf
-normalOrderReduction :: forall repr a.
-  Abstractable repr =>
-  IfThenElseable repr =>
-  SomeData repr a -> SomeData repr a
-normalOrderReduction = nor
-  where
-  -- | normal-order reduction
-  nor :: SomeData repr b -> SomeData repr b
-  nor = \case
-    Data (Lam f) -> lam (nor Fun.. f)
-    Data (Lam1 f) -> lam1 (nor Fun.. f)
-    Data (x :@ y) -> case whnf x of
-      Data (Lam1 f) -> nor (f y)
-      x' -> nor x' .@ nor y
-    Data (IfThenElse test ok ko) ->
-      case nor test of
-        Data (Constant b :: Data (Constantable Bool) repr Bool) ->
-          if b then nor ok else nor ko
-        t -> ifThenElse (nor t) (nor ok) (nor ko)
-    x -> x
-  -- | weak-head normal-form
-  whnf :: SomeData repr b -> SomeData repr b
-  whnf = \case
-    Data (x :@ y) -> case whnf x of
-      Data (Lam1 f) -> whnf (f y)
-      x' -> x' .@ y
-    x -> x
diff --git a/src/Symantic/Typed/Trans.hs b/src/Symantic/Typed/Trans.hs
deleted file mode 100644 (file)
index 1d46490..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-{-# LANGUAGE ConstraintKinds #-} -- For type class synonyms
-{-# LANGUAGE PolyKinds #-}
-{-# LANGUAGE DefaultSignatures #-} -- For adding Trans constraints
-module Symantic.Typed.Trans where
-
-import Data.Function ((.))
-import Data.Kind (Type)
-
--- * Type family 'Unlifted'
-type family Unlifted (repr :: Type -> Type) :: Type -> Type
-
--- * Class 'Trans'
--- | A 'trans'formation from an interpreter @(from)@ to an interpreter @(to)@.
-class Trans from to where
-  trans :: from a -> to a
-
--- * Class 'BiTrans'
--- | Convenient type class synonym.
--- Note that this is not necessarily a bijective 'trans'lation,
--- a 'trans' being not necessarily injective nor surjective.
-type BiTrans from to = (Trans from to, Trans to from)
-
--- ** Class 'Liftable'
--- | Convenient type class synonym for using 'Unlifted'
-type Liftable repr = Trans (Unlifted repr) repr
-lift :: forall repr a.
-  Liftable repr =>
-  Unlifted repr a -> repr a
-lift = trans @(Unlifted repr)
-{-# INLINE lift #-}
-
-unlift :: forall repr a.
-  Trans repr (Unlifted repr) =>
-  repr a -> Unlifted repr a
-unlift = trans @repr
-{-# INLINE unlift #-}
-
--- ** Class 'Unliftable'
--- | Convenient type class synonym for using 'Unlifted'
-type Unliftable repr = Trans repr (Unlifted repr)
-
--- * Class 'Trans1'
-class Trans1 from to where
-  trans1 ::
-    (from a -> from b) ->
-    to a -> to b
-  default trans1 ::
-    BiTrans from to =>
-    (from a -> from b) ->
-    to a -> to b
-  trans1 f = trans . f . trans
-  {-# INLINE trans1 #-}
-
--- ** Class 'Liftable1'
--- | Convenient type class synonym for using 'Unlifted'
-type Liftable1 repr = Trans1 (Unlifted repr) repr
-lift1 :: forall repr a b.
-  Liftable1 repr =>
-  (Unlifted repr a -> Unlifted repr b) ->
-  repr a -> repr b
-lift1 = trans1 @(Unlifted repr)
-{-# INLINE lift1 #-}
-
--- * Class 'Trans2'
-class Trans2 from to where
-  trans2 ::
-    (from a -> from b -> from c) ->
-    to a -> to b -> to c
-  default trans2 ::
-    BiTrans from to =>
-    (from a -> from b -> from c) ->
-    to a -> to b -> to c
-  trans2 f a b = trans (f (trans a) (trans b))
-  {-# INLINE trans2 #-}
-
--- ** Class 'Liftable2'
--- | Convenient type class synonym for using 'Unlifted'
-type Liftable2 repr = Trans2 (Unlifted repr) repr
-lift2 :: forall repr a b c.
-  Liftable2 repr =>
-  (Unlifted repr a -> Unlifted repr b -> Unlifted repr c) ->
-  repr a -> repr b -> repr c
-lift2 = trans2 @(Unlifted repr)
-{-# INLINE lift2 #-}
-
--- * Class 'Trans3'
-class Trans3 from to where
-  trans3 ::
-    (from a -> from b -> from c -> from d) ->
-    to a -> to b -> to c -> to d
-  default trans3 ::
-    BiTrans from to =>
-    (from a -> from b -> from c -> from d) ->
-    to a -> to b -> to c -> to d
-  trans3 f a b c = trans (f (trans a) (trans b) (trans c))
-  {-# INLINE trans3 #-}
-
--- ** Class 'Liftable3'
--- | Convenient type class synonym for using 'Unlifted'
-type Liftable3 repr = Trans3 (Unlifted repr) repr
-lift3 :: forall repr a b c d.
-  Liftable3 repr =>
-  (Unlifted repr a -> Unlifted repr b -> Unlifted repr c -> Unlifted repr d) ->
-  repr a -> repr b -> repr c -> repr d
-lift3 = trans3 @(Unlifted repr)
-{-# INLINE lift3 #-}
-
-{-
--- * Type 'Any'
--- | A newtype to disambiguate the 'Trans' instance to any other interpreter when there is also one or more 'Trans's to other interpreters with a different interpretation than the generic one.
-newtype Any repr a = Any { unAny :: repr a }
-type instance Unlifted (Any repr) = repr
-instance Trans (Any repr) repr where
-  trans = unAny
-instance Trans1 (Any repr) repr
-instance Trans2 (Any repr) repr
-instance Trans3 (Any repr) repr
-instance Trans repr (Any repr) where
-  trans = Any
-instance Trans1 repr (Any repr)
-instance Trans2 repr (Any repr)
-instance Trans3 repr (Any repr)
--}
diff --git a/src/Symantic/Typed/View.hs b/src/Symantic/Typed/View.hs
deleted file mode 100644 (file)
index 198a989..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE ImplicitPrelude #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE PatternSynonyms #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeApplications #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE UndecidableInstances #-} -- For Show (SomeData a)
-module Symantic.Typed.View where
-
-import Data.Int (Int)
-import Data.String
-import Text.Show
-import qualified Data.Function as Fun
-import qualified Prelude
-
-import Symantic.Parser.Grammar.Fixity
-import Symantic.Typed.Lang
-import Symantic.Typed.Data
-import Symantic.Typed.Trans
-
-data View a where
-  View :: (ViewEnv -> ShowS) -> View a
-  ViewUnifix :: Unifix -> String -> String -> View (a -> b)
-  ViewInfix :: Infix -> String -> String -> View (a -> b -> c)
-  ViewApp :: View (b -> a) -> View b -> View a
-
-runView :: View a -> ViewEnv -> ShowS
-runView (View v) env = v env
-runView (ViewInfix _op name _infixName) _env = showString name
-runView (ViewUnifix _op name _unifixName) _env = showString name
-runView (ViewApp f x) env =
-  pairView env op Fun.$
-    runView f env{viewEnv_op = (op, SideL) } Fun..
-    showString " " Fun..
-    runView x env{viewEnv_op = (op, SideR) }
-  where op = infixN 10
-
--- | Unusual, but enables to leverage default definition of methods.
-type instance Unlifted View = View
-instance Trans View View where
-  trans = Fun.id
-
-instance IsString (View a) where
-  fromString s = View Fun.$ \_env -> showString s
-instance Show (View a) where
-  showsPrec p = (`runView` ViewEnv
-    { viewEnv_op = (infixN p, SideL)
-    , viewEnv_pair = pairParen
-    , viewEnv_lamDepth = 1
-    })
-instance Show (SomeData View a) where
-  showsPrec p (SomeData x) = showsPrec p (trans @_ @View x)
-
-data ViewEnv
-  = ViewEnv
-  { viewEnv_op :: (Infix, Side)
-  , viewEnv_pair :: Pair
-  , viewEnv_lamDepth :: Int
-  }
-
-pairView :: ViewEnv -> Infix -> ShowS -> ShowS
-pairView env op s =
-  if isPairNeeded (viewEnv_op env) op
-  then showString o Fun.. s Fun.. showString c
-  else s
-  where (o,c) = viewEnv_pair env
-
-instance Abstractable View where
-  var = Fun.id
-  lam f = viewLam "x" f
-  lam1 f = viewLam "u" f
-  ViewInfix op _name infixName .@ ViewApp x y = View Fun.$ \env ->
-    pairView env op Fun.$
-      runView x env{viewEnv_op=(op, SideL)} Fun..
-      showString " " Fun.. showString infixName Fun.. showString " " Fun..
-      runView y env{viewEnv_op=(op, SideR)}
-  ViewInfix op name _infixName .@ x = View Fun.$ \env ->
-    showParen Prelude.True Fun.$
-      runView x env{viewEnv_op=(op, SideL)} Fun..
-      showString " " Fun.. showString name
-  f .@ x = ViewApp f x
-viewLam :: String -> (View a -> View b) -> View (a -> b)
-viewLam varPrefix f = View Fun.$ \env ->
-  pairView env op Fun.$
-    let x = showString varPrefix Fun..
-            showsPrec 0 (viewEnv_lamDepth env) in
-    -- showString "Lam1 (" .
-    showString "\\" Fun.. x Fun.. showString " -> " Fun..
-    runView (f (View (\_env -> x))) env
-      { viewEnv_op = (op, SideL)
-      , viewEnv_lamDepth = Prelude.succ (viewEnv_lamDepth env)
-      }
-    -- . showString ")"
-  where
-  op = infixN 0
-instance Anythingable View
-instance Bottomable View where
-  bottom = "<hidden>"
-instance Show c => Constantable c View where
-  constant c = View Fun.$ \_env -> shows c
-instance Eitherable View where
-  left = "Left"
-  right = "Right"
-instance Equalable View where
-  equal = ViewInfix (infixN 4) "(==)" "=="
-instance Listable View where
-  cons = ViewInfix (infixR 5) "(:)" ":"
-  nil = "[]"
-instance Maybeable View where
-  nothing = "Nothing"
-  just = "Just"
index 53dda53caeacc2665611ae70d6c777df31705d41..96f13c05491c812f3542c61d5fd457f60d2b3e8a 100644 (file)
@@ -60,11 +60,7 @@ common boilerplate
     -Wincomplete-uni-patterns
     -Wincomplete-record-updates
     -Wpartial-fields
-    -fhide-source-paths
-    ---freverse-errors
     -fprint-potential-instances
-  ghc-prof-options: -eventlog -fprof-auto
-                 -- -fprof-auto-calls
 
 library
   import: boilerplate
@@ -75,7 +71,6 @@ library
     Symantic.Parser
     Symantic.Parser.Grammar
     Symantic.Parser.Grammar.Combinators
-    Symantic.Parser.Grammar.Fixity
     Symantic.Parser.Grammar.ObserveSharing
     Symantic.Parser.Grammar.Optimize
     Symantic.Parser.Grammar.Production
@@ -88,12 +83,6 @@ library
     Symantic.Parser.Machine.Optimize
     Symantic.Parser.Machine.Program
     Symantic.Parser.Machine.View
-    Symantic.Typed.Data
-    Symantic.Typed.Lang
-    Symantic.Typed.Letable
-    Symantic.Typed.Optim
-    Symantic.Typed.Trans
-    Symantic.Typed.View
   default-extensions:
     BangPatterns,
     DataKinds,
@@ -118,8 +107,9 @@ library
     deepseq >= 1.4,
     ghc-prim,
     hashable,
-    -- Needed to use Language.Haskell.Ppr.Lib.pprExp
+    -- For Language.Haskell.Ppr.Lib.pprExp
     pretty >= 1.1,
+    symantic-base >= 0.1,
     template-haskell >= 2.16,
     text,
     transformers,
@@ -167,6 +157,7 @@ library parsers
     megaparsec >= 9.0,
     process >= 1.6,
     strict >= 0.4,
+    symantic-base >= 0.1,
     tasty >= 0.11,
     tasty-golden >= 2.3,
     template-haskell >= 2.16,