diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,94 @@
+
+# 0.8.2
+
+Thank you again to Skyfold (Martin P.)
+
+- Deprecation warning for the KnownNats class and its instances: the KnownVal
+  can be used instead.
+- Instances to IntMap, Map and Set to convert directly from '[a] or '[ '(key,val) ]
+- The ErrorMessage instance for KnownVal to show information about types 
+- Add KnownVal instance for typeable types, this can be used as Show for
+  the types presented at the kind level. 
+- Fix the Test.Alg test description
+- Remove doc-tests from all Fcf.Alg modules and write the corresponding test modules
+- Some cleaning
+- Add depracation and warning pragmas to text modules.
+
+
+# 0.8.1
+
+20230410
+
+Thank you to Skyfold (Martin P.)
+
+- Generalized KnownVal instances
+- Initialized the HSpec use and test directory organization
+- Added flake definitions
+- Updated stack version (not tested with stack)
+- Removed shell.nix
+- Fcf.Data.Set doctests removed and replaced with Test.Data.Set
+- Fcf.Alg.List doctests removed and replaced with Test.Alg.List
+
+
+# 0.8.0
+
+20230226
+
+- Fcf.Data.Char for GHC 9.2.X or higher, the Text will start using this.
+- Fcf.Data.Tuple with Swap method
+- Fcf.Data.Reflect gives methods to turn type-level structures into value-level.
+  These include instances for trees, natMaps, maps, lists, and text. Text instances
+  are only for GHC 9.2.X or higher.
+- Fcf.Data.Symbol for GHC 9.2.x or higher, the Text will start using this.
+- Deprecate the current Text and Text.Internal modules and introduce new using
+  the Symbol module (these are for GHC 9.2.x or higher).
+- Add new dependencies, containers and text (for the Reflect module).
+- Several hlint suggestion fixes included
+
+The "NewText" module could have more methods that the counterpart already has.
+Also, the Reflect module could have more typical instances.
+
+The test will be moved into the test directory and away from the doctests, which
+in turn, will be deprecated. The doctests would be otherwise nice, but they are
+difficult (laborous) to support for several different ghc versions.
+
+This also includes Data.List.Utils and there Foldl and MaybeToList methods.
+
+
+# 0.7.2
+
+2023015
+
+- Add notes about defunctionalization and associated code examples
+- Add helper module for Foldl method (it would be better at first-class-families lib).
+
+# 0.7.1
+
+20220601
+
+ - Clean up several modules (remove extra spaces and paranthesis)
+ - Update doctest function and remove Glob dependency
+ - Update ci pipeline to do tests with 9.0 and 9.2
+
+# 0.7.0
+
+20220424
+
+ - Add preliminary support for Applicative and Monadic computations
+ - Small whitespace fixes
+ - Added dependency for mtl (to get Identity)
+ - Add new compiler versions for tests and drop some old
+ - Start referring to cabal version 3.0
+
+# 0.6.1
+
+20210130
+
+Start using the github actions and remove travis CI.
+
 # 0.6.0
+
+20210130
 
  - use symbol as text representation (we can split predefined char-sets, as shown
    by the Csongor at https://kcsongor.github.io/symbol-parsing-haskell/ see also
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -56,14 +56,38 @@
 cabal test 
 ```
 
-The doc-tests both document and work as main testing mechanism for this lib. 
+If you are flakes user, `nix develop -c zsh` (or without that `-c zsh`) works as well.
 
+The doc-tests both document and work partly as testing mechanism for this lib. Please 
+do note that we are moving away from the doc-tests and building the testing modules 
+under `test` directory.
+
 If you don't use nix, `cabal install fcf-containers` should be enough. This
 package has almost as good number of dependencies as the first-class-families.
 
 
 ## Example
 
+
+### Test cases as examples
+
+The  
+[test directory](https://github.com/gspia/fcf-containers/blob/master/test)
+contains a lot of useful examples.  There you will find out, how to apply most
+of the methods: examples that only work on "compile time", and examples on how
+to get the results from type level calculations to value level (see the Reflect
+test module and the `fromType` method applications, also in some other testing
+modules).
+
+
+### Three example programs calculating something
+
+These are a bit larger examples, but not yet too large: somewhat convenient small 
+module size.  Idea was to take an algorithm, and convert it to a type-level 
+computation, or in some other way give an example of methods that this library
+provides.
+
+
 See [Orbits.hs](https://github.com/gspia/fcf-containers/blob/master/examples/Orbits.hs). 
 It shows how to solve a real problem,
 what PRAGMAs are probably needed etc.
@@ -72,7 +96,10 @@
 cabal run orbits 
 ```
 
-There is also another example that show how to use MapC, see
+There is also another Advent of Code problem, see the Carbcombat file.
+
+
+To see, how to use MapC, take a look at
 [Haiku.hs](https://github.com/gspia/fcf-containers/blob/master/examples/Haiku.hs)
 
 ```
@@ -80,6 +107,16 @@
 ```
 
 
+### Other example material
+
+Please, do take a look of the notes made for the Helsinki Haskell meetup
+on 11th January 2023
+[notes](https://github.com/gspia/fcf-containers/blob/master/examples/20230111_hhslides.md)
+and the associated 
+[code examples](https://github.com/gspia/fcf-containers/blob/master/examples/20230111_hhmeetup.hs).
+
+
+
 ## Random Notes
 
 ### Partiality and anonymous functions
@@ -91,7 +128,7 @@
 We don't have lambdas, but if you can write the helper function in point-free
 form, it might can be used directly without any global function definition.
 Remember, that `(<=<)` corresponds to term-level `(.)` and `(=<<)` to 
-term-level function  application `($)`. See also Maguire's book 
+term-level function application `($)`. See also Maguire's book 
 (Thinking with Types).
 
 
@@ -167,6 +204,7 @@
 
 Source also contains a lot of examples, see
 [fcf-containers](https://github.com/gspia/fcf-containers/tree/master/src/Fcf).
-
+The examples will be left near the code, even thou the doctest runs will be 
+removed and replaced with real tests at the test-directory.
 
 Happy :kinding!
diff --git a/TODO.md b/TODO.md
--- a/TODO.md
+++ b/TODO.md
@@ -1,18 +1,28 @@
 # TODO
 
-## Examples:
+## Examples and tests:
 
-E.g. add examples using the other data structures.
+E.g. add examples using the other data structures. Start building the
+tests in the test-directory. The doc-tests are hard to keep working for
+several GHC versions at the same time and deprecate them.
 
+This will also mean that the code modules will be come a bit cleaner.
+
+
 ## Data structures:
 
-Add the missing methods and doctests.
+Add the missing methods and tests. Move doctests under tests.
 
 - Set
 - NatMap
 - Graphs
 - MapB (Map data structure) but implemented with the balanced trees
 - MapC 
+- Text (e.g. those folding methods)
+
+
+The test structuring requires a bit thinking. New dependencies or some 
+simple structure to help here?
  
 
 ## Morphisms:
diff --git a/default.nix b/default.nix
--- a/default.nix
+++ b/default.nix
@@ -1,5 +1,13 @@
 { 
-  # compiler ? "ghc881" 
+  # compiler ? "ghc884" 
+  # compiler ? "ghc8107"
+  # compiler ? "ghc902"
+  # compiler ? "ghc922"
+  # compiler ? "ghc924"
+  # compiler ? "ghc925" # listlike-tests are extremely slow
+  # compiler ? "ghc926" # not yet
+  # compiler ? "ghc942"
+  # compiler ? "ghc943"
 } :
 let
   config = {
@@ -16,12 +24,18 @@
           # });
           first-class-families = self.callCabal2nix "first-class-families" 
           #   ~/gito/first-class-families {}; 
-            (pkgs.fetchFromGitHub { # 0.8
+            (pkgs.fetchFromGitHub { # 0.8.0.1
               owner  = "Lysxia";
               repo   = "first-class-families";
-              rev    = "4a0bf3ea9c125bb4009b61ce70b1a5339b7b2072";
-              sha256 = "14387mpfvds226iynkpay3aaqamvxznxjsmg2qcwdxafdvxmyq9z";
+              rev    = "933c2527de9bfcb162e0eebcbcdac4f28a39bd3b";
+              sha256 = "0k66s3bg71pm890zgr5w88zv7vcrxfwd74c0dcn945k91nzn41b2";
             }) {};
+            # (pkgs.fetchFromGitHub { # 0.8.0.1
+            #   owner  = "Lysxia";
+            #   repo   = "first-class-families";
+            #   rev    = "d4780864ed9b11343b7b26050e39b2048a8e61f6";
+            #   sha256 = "1iw0dryz66z4k9lsj1kayf17xs38i8bdk9aqi2qz49vcbhnfw8pd";
+            # }) {};
             # something for the next version?
             #  rev    = "9fe4ce36cf1cd4b0f5af59c923c15b9085c48cd6";
             #  sha256 = "1677ylhhf1mwwfs6j2p6gbn2f6mzsx4zmaihz8v9v07h845wz8l7";
@@ -47,7 +61,8 @@
   adjust-for-ghc = drv: {
     executableSystemDepends = [
       hpkgs.ghcid
-      hpkgs.ghcide
+      # hpkgs.ghcide
+      hpkgs.haskell-language-server
       hpkgs.cabal-install
     ];
     buildDepends = [
diff --git a/examples/Crabcombat.hs b/examples/Crabcombat.hs
--- a/examples/Crabcombat.hs
+++ b/examples/Crabcombat.hs
@@ -101,7 +101,7 @@
     (
     Foldr (N.+) 0
     =<< Uncurry (ZipWith (N.*))
-    =<< Bimap ((MToN 1) <=< Length) Reverse
+    =<< Bimap (MToN 1 <=< Length) Reverse
     =<< AsPair
     =<< Fst
     =<< PlayGame '[] input
@@ -114,6 +114,7 @@
 -- Does not compile on my machine (not even with the -freduction-depth=0 at cabal),
 -- not enough memory
 -- Ghci also gets 'Killed'.
+{-
 type Input =
     '( '[21, 50,  9, 45, 16, 47, 27, 38, 29, 48, 10, 42, 32, 31, 41, 11,  8, 33, 25, 30, 12, 40,  7, 23, 46]
      , '[22, 20, 44,  2, 26, 17, 34, 37, 43,  5, 15, 18, 36, 19, 24, 35,  3, 13, 14,  1,  6, 39, 49,  4, 28]
@@ -136,7 +137,7 @@
     '( '[21, 50,  9, 45, 16, 47, 27, 38, 29, 48, 10,   40,  7, 23, 46]
      , '[22, 20, 44,  2, 26, 17, 34, 37, 43,  5, 15,   39, 49,  4, 28]
      ) -- :: ([Nat], [Nat])
-
+-}
 
 
 
diff --git a/examples/Haiku.hs b/examples/Haiku.hs
--- a/examples/Haiku.hs
+++ b/examples/Haiku.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP                    #-}
 {-# LANGUAGE DataKinds              #-}
 {-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE ScopedTypeVariables    #-}
@@ -16,9 +17,14 @@
 
 This exemplifies the use of @MapC@ and @Text@.
 
+Idea of the type-level program.  We want to check that the given type-level
+Haiku is correctly composed.  As inputs, we get the Haiku as words written
+in syllables.  The allowed Haiku-structure, that is, the number of expected
+syllables per line, is given separetely.  We require 5, 7 and 5 syllables.
+
 Exercises:
  - Write a method for structurally wrong Haiku's and output something other in those cases
- - Vocabulary with syllables is somewhat parameterized (except WSmap) but 
+ - Vocabulary with syllables is somewhat parameterized (except WSmap) but
    not the other half.
    Change CheckHaiku to accepts the vocabulary to use and the haiku the check.
 
@@ -36,7 +42,11 @@
 import           Fcf.Data.List as L
 
 import           Fcf.Data.MapC as M
+#if __GLASGOW_HASKELL__ >= 902
+import           Fcf.Data.NewText as T
+#else
 import           Fcf.Data.Text as T
+#endif
 
 import           Fcf.Alg.List (Equal)
 
@@ -124,7 +134,11 @@
 -- | We left something here as well. We don't want this executable to compile
 -- if the Haiku is not ok.
 showHaiku
+#if __GLASGOW_HASKELL__ >= 902
+    :: forall symbol. (symbol ~ Eval (Unpack =<< Haiku), 'True ~ Eval CheckHaiku)
+#else
     :: forall symbol. (symbol ~ Eval (ToSymbol =<< Haiku), 'True ~ Eval CheckHaiku)
+#endif
     => String
 showHaiku = TL.symbolVal @symbol Proxy
 
diff --git a/examples/Orbits.hs b/examples/Orbits.hs
--- a/examples/Orbits.hs
+++ b/examples/Orbits.hs
@@ -14,7 +14,7 @@
 Example on how to do compile-time (ie type-level) computations and how
 to get the results into use on term-level (ie runtime).
 
-The original problem is described in 
+The original problem is described in
 [aoc 19 d6](https://adventofcode.com/2019/day/6). We use the described
 example input data in a bit different form. See the link for the
 original data and answer.
diff --git a/fcf-containers.cabal b/fcf-containers.cabal
--- a/fcf-containers.cabal
+++ b/fcf-containers.cabal
@@ -1,3 +1,4 @@
+Cabal-version:       3.0
 Name:                fcf-containers
 Synopsis:            Data structures and algorithms for first-class-families
 Description:
@@ -6,28 +7,35 @@
     contents of containers-package and show how these can be used. Everything is
     based on the ideas given in the first-class-families -package.
 Homepage:            https://github.com/gspia/fcf-containers
-Version:             0.6.0
+Version:             0.8.2
 Build-type:          Simple
 Author:              gspia
 Maintainer:          iahogsp@gmail.com
-License:             BSD3
+License:             BSD-3-Clause
 License-file:        LICENSE
 Category:            Other
 Copyright:           gspia (c) 2020-
-Extra-source-files:  README.md, TODO.md, CHANGELOG.md, default.nix, shell.nix
-Cabal-version:       1.24
-Tested-With:         GHC ==8.10.3 || ==8.8.4 || ==8.6.5 || ==8.4.4
+Extra-source-files:  README.md, TODO.md, CHANGELOG.md, default.nix, flake.nix, flake.lock
+Tested-With:         GHC ==9.2.4 || ==9.0.2 || ==8.10.7
 
 
 library
   hs-source-dirs:    src
-  exposed-modules:   Fcf.Data.MapC
+  exposed-modules:   Fcf.Control.Monad
                    , Fcf.Data.Bitree
+                   , Fcf.Data.Char
+                   , Fcf.Data.List.Utils
+                   , Fcf.Data.MapC
                    , Fcf.Data.NatMap
+                   , Fcf.Data.Reflect
                    , Fcf.Data.Set
-                   , Fcf.Data.Text
+                   , Fcf.Data.Symbol
                    , Fcf.Data.Text.Internal
+                   , Fcf.Data.Text
+                   , Fcf.Data.NewText
+                   , Fcf.Data.OldText
                    , Fcf.Data.Tree
+                   , Fcf.Data.Tuple
                    , Fcf.Alg.List
                    , Fcf.Alg.Morphism
                    , Fcf.Alg.Nat
@@ -35,8 +43,11 @@
                    , Fcf.Alg.Sort
                    , Fcf.Alg.Symbol
                    , Fcf.Alg.Tree
-  build-depends:     base >= 4.9 && < 4.18
+  build-depends:     base >= 4.9 && < 4.22
+                   , containers
                    , first-class-families >= 0.8 && < 0.9
+                   , ghc-prim
+                   , text
   ghc-options:      -Wall
   default-language:  Haskell2010
   -- ghc-options:
@@ -61,6 +72,9 @@
   build-depends:    base
                   , first-class-families
                   , fcf-containers
+  ghc-options:
+      -Wall
+      -freduction-depth=0
 
 Executable crabcombat
   hs-source-dirs:   examples
@@ -80,10 +94,28 @@
   hs-source-dirs:      test
   main-is:             test.hs
   default-language:    Haskell2010
+  other-modules:       Test.Alg
+                     , Test.Alg.List
+                     , Test.Alg.Morphism
+                     , Test.Alg.Nat
+                     , Test.Alg.Other
+                     , Test.Alg.Sort
+                     , Test.Alg.Symbol
+                     , Test.Alg.Tree
+                     , Test.Control
+                     , Test.Control.Monad
+                     , Test.Data
+                     , Test.Data.Reflect
+                     , Test.Data.Set
   build-depends:
       base
     , first-class-families
     , fcf-containers
+    , hspec
+    , containers
+    , text
+--  ghc-options:
+--      -freduction-depth=0
 
 test-suite fcf-doctest
   type:                exitcode-stdio-1.0
@@ -93,10 +125,10 @@
   if impl(ghc >= 8.6)
     build-depends:
       base
+      , doctest
       , first-class-families
       , fcf-containers
-      , doctest
-      , Glob
+      , ghc-prim
   else
     buildable: False
 
diff --git a/flake.lock b/flake.lock
new file mode 100644
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,44 @@
+{
+  "nodes": {
+    "nix-filter": {
+      "locked": {
+        "lastModified": 1666547822,
+        "narHash": "sha256-razwnAybPHyoAyhkKCwXdxihIqJi1G6e1XP4FQOJTEs=",
+        "owner": "numtide",
+        "repo": "nix-filter",
+        "rev": "1a3b735e13e90a8d2fd5629f2f8363bd7ffbbec7",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "ref": "master",
+        "repo": "nix-filter",
+        "type": "github"
+      }
+    },
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1674990008,
+        "narHash": "sha256-4zOyp+hFW2Y7imxIpZqZGT8CEqKmDjwgfD6BzRUE0mQ=",
+        "owner": "nixos",
+        "repo": "nixpkgs",
+        "rev": "d2bbcbe6c626d339b25a4995711f07625b508214",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nixos",
+        "ref": "nixpkgs-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "nix-filter": "nix-filter",
+        "nixpkgs": "nixpkgs"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,72 @@
+{
+  description = "Data structures and algorithms for first-class-families";
+
+  inputs = {
+    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
+    nix-filter.url = "github:numtide/nix-filter/master";
+  };
+
+  outputs = { self, nixpkgs, nix-filter }: 
+    let
+      pkgs = import nixpkgs { system = "x86_64-linux"; };
+
+      # filter = import nix-filter { };
+
+      ghcVersion = "925";
+      # ghcVersion = "92";
+      # ghcVersion = "902";
+
+      src = nix-filter.lib {
+        root = ./.;
+        include = [
+          (nix-filter.lib.inDirectory "src")
+          (nix-filter.lib.inDirectory "examples")
+          (nix-filter.lib.inDirectory "test")
+          (nix-filter.lib.matchExt "hs")
+          ./fcf-containers.cabal
+          ./cabal.project
+          ./LICENSE
+        ];
+      };
+
+      fcf-containers = hself: hself.callCabal2nix "fcf-containers" src {};
+
+      myHaskellPackages = pkgs.haskell.packages."ghc${ghcVersion}".override {
+        overrides = hself: hsuper: {
+          # fcf-containers = hself.callCabal2nix "fcf-containers" sources.fcf-containers {};
+          # fcf-containers = (import sources.fcf-containers {});
+          fcf-containers = fcf-containers hself;
+          # ListLike = pkgs.haskell.lib.dontCheck hsuper.ListLike;
+          # type-of-html = pkgs.haskell.lib.doBenchmark (hself.callPackage ./nix/type-of-html.nix {inherit src;});
+          # type-of-html = hself.callCabal2nix "type-of-html" src {};
+          # optics-core = hsuper.optics-core.overrideAttrs(old: {
+          #   configureFlags = "-f explicit-generic-labels";
+          #   patches = [./optics-core.patch];
+          # });
+        };
+      };
+
+      shell = myHaskellPackages.shellFor {
+        packages = p: [
+          p.fcf-containers
+        ];
+        buildInputs = with pkgs.haskell.packages."ghc${ghcVersion}"; [
+          myHaskellPackages.cabal-install
+          ghcid
+          (pkgs.haskell-language-server.override { supportedGhcVersions = [ "${ghcVersion}" ]; })
+          hlint
+          # implicit-hie
+          # cabal2nix
+        ];
+        withHoogle = true;
+        doBenchmark = true;
+      };
+
+    in
+      {
+        library = fcf-containers;
+        # packages.x86_64-linux.default = ;
+        devShell.x86_64-linux = shell;
+        inherit pkgs;
+      };
+}
diff --git a/shell.nix b/shell.nix
deleted file mode 100644
--- a/shell.nix
+++ /dev/null
@@ -1,9 +0,0 @@
-{ nixpkgs ? import <nixpkgs> {}
-/* , compiler ? "ghc822" */
-} : 
-let
-  inherit (nixpkgs) pkgs;
-  /* drv = import ./. { inherit compiler; }; */
-  drv = import ./. { };
-in
-if pkgs.lib.inNixShell then drv.env else drv
diff --git a/src/Fcf/Alg/List.hs b/src/Fcf/Alg/List.hs
--- a/src/Fcf/Alg/List.hs
+++ b/src/Fcf/Alg/List.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE DataKinds              #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
 {-# LANGUAGE TypeOperators          #-}
@@ -21,6 +19,8 @@
 This module also contains other list-related functions (that might move to
 other place some day).
 
+To see examples, please do take a look of the respective test module.
+
 -}
 
 --------------------------------------------------------------------------------
@@ -41,13 +41,6 @@
 
 --------------------------------------------------------------------------------
 
--- For the doctests:
-
--- $setup
--- >>> import           Fcf.Combinators
-
---------------------------------------------------------------------------------
-
 -- | Base functor for a list of type @[a]@.
 data ListF a b = ConsF a b | NilF
 
@@ -57,7 +50,7 @@
 
 --------------------------------------------------------------------------------
 
--- | ListToFix can be used to turn a norma type-level list into the base
+-- | ListToFix can be used to turn a normal type-level list into the base
 -- functor type ListF, to be used with e.g. Cata. For examples in use, see
 -- 'LenAlg' and 'SumAlg'.
 --
@@ -67,8 +60,8 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (ListToFix '[1,2,3])
--- Eval (ListToFix '[1,2,3]) :: Fix (ListF Nat)
+-- > :kind! Eval (ListToFix '[1,2,3])
+-- Eval (ListToFix '[1,2,3]) :: Fix (ListF TL.Natural)
 -- = 'Fix ('ConsF 1 ('Fix ('ConsF 2 ('Fix ('ConsF 3 ('Fix 'NilF))))))
 data ListToFix :: [a] -> Exp (Fix (ListF a))
 type instance Eval (ListToFix '[]) = 'Fix 'NilF
@@ -78,8 +71,8 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Cata LenAlg =<< ListToFix '[1,2,3])
--- Eval (Cata LenAlg =<< ListToFix '[1,2,3]) :: Nat
+-- > :kind! Eval (Cata LenAlg =<< ListToFix '[1,2,3])
+-- Eval (Cata LenAlg =<< ListToFix '[1,2,3]) :: TL.Natural
 -- = 3
 data LenAlg :: Algebra (ListF a) Nat
 type instance Eval (LenAlg 'NilF) = 0
@@ -89,8 +82,8 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Cata SumAlg =<< ListToFix '[1,2,3,4])
--- Eval (Cata SumAlg =<< ListToFix '[1,2,3,4]) :: Nat
+-- > :kind! Eval (Cata SumAlg =<< ListToFix '[1,2,3,4])
+-- Eval (Cata SumAlg =<< ListToFix '[1,2,3,4]) :: TL.Natural
 -- = 10
 data SumAlg :: Algebra (ListF Nat) Nat
 type instance Eval (SumAlg 'NilF) = 0
@@ -100,8 +93,8 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Cata ProdAlg =<< ListToFix '[1,2,3,4])
--- Eval (Cata ProdAlg =<< ListToFix '[1,2,3,4]) :: Nat
+-- > :kind! Eval (Cata ProdAlg =<< ListToFix '[1,2,3,4])
+-- Eval (Cata ProdAlg =<< ListToFix '[1,2,3,4]) :: TL.Natural
 -- = 24
 data ProdAlg :: Algebra (ListF Nat) Nat
 type instance Eval (ProdAlg 'NilF) = 1
@@ -113,8 +106,9 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (ListToParaFix '[1,2,3])
--- Eval (ListToParaFix '[1,2,3]) :: Fix (ListF (Nat, [Nat]))
+-- > :kind! Eval (ListToParaFix '[1,2,3])
+-- Eval (ListToParaFix '[1,2,3]) :: Fix
+--                                    (ListF (TL.Natural, [TL.Natural]))
 -- = 'Fix
 --     ('ConsF
 --        '(1, '[2, 3])
@@ -130,8 +124,8 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Para DedupAlg =<< ListToParaFix '[1,1,3,2,5,1,3,2])
--- Eval (Para DedupAlg =<< ListToParaFix '[1,1,3,2,5,1,3,2]) :: [Nat]
+-- > :kind! Eval (Para DedupAlg =<< ListToParaFix '[1,1,3,2,5,1,3,2])
+-- Eval (Para DedupAlg =<< ListToParaFix '[1,1,3,2,5,1,3,2]) :: [TL.Natural]
 -- = '[5, 1, 3, 2]
 data DedupAlg :: RAlgebra (ListF (a,[a])) [a]
 type instance Eval (DedupAlg 'NilF) = '[]
@@ -146,8 +140,8 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Sliding 3 '[1,2,3,4,5,6])
--- Eval (Sliding 3 '[1,2,3,4,5,6]) :: [[Nat]]
+-- > :kind! Eval (Sliding 3 '[1,2,3,4,5,6])
+-- Eval (Sliding 3 '[1,2,3,4,5,6]) :: [[TL.Natural]]
 -- = '[ '[1, 2, 3], '[2, 3, 4], '[3, 4, 5], '[4, 5, 6], '[5, 6], '[6]]
 data Sliding :: Nat -> [a] -> Exp [[a]]
 type instance Eval (Sliding n lst) =
@@ -172,14 +166,14 @@
 type instance Eval (EvensAlg 'NilF) = '[]
 type instance Eval (EvensAlg ('ConsF _ rst )) = Eval (EvensStrip =<< Strip rst)
 
--- | This picks up the elements on even positions on a list and is an 
+-- | This picks up the elements on even positions on a list and is an
 -- example on how to use Histo. This example is
 -- from Tim Williams, Recursion Schemes by example.
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Evens =<< RunInc 8)
--- Eval (Evens =<< RunInc 8) :: [Nat]
+-- > :kind! Eval (Evens =<< RunInc 8)
+-- Eval (Evens =<< RunInc 8) :: [TL.Natural]
 -- = '[2, 4, 6, 8]
 data Evens :: [a] -> Exp [a]
 type instance Eval (Evens lst) = Eval (Histo EvensAlg =<< ListToFix lst)
@@ -200,8 +194,8 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (RunInc 8)
--- Eval (RunInc 8) :: [Nat]
+-- > :kind! Eval (RunInc 8)
+-- Eval (RunInc 8) :: [TL.Natural]
 -- = '[1, 2, 3, 4, 5, 6, 7, 8]
 data RunInc :: Nat -> Exp [Nat]
 type instance Eval (RunInc n) = Eval (Reverse =<< Unfoldr ListRunAlg n)
@@ -213,8 +207,8 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Sum '[1,2,3])
--- Eval (Sum '[1,2,3]) :: Nat
+-- > :kind! Eval (Sum '[1,2,3])
+-- Eval (Sum '[1,2,3]) :: TL.Natural
 -- = 6
 data Sum :: [Nat] -> Exp Nat
 type instance Eval (Sum ns) = Eval (Foldr (+) 0 ns)
@@ -234,8 +228,8 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (MToN 1 3)
--- Eval (MToN 1 3) :: [Nat]
+-- > :kind! Eval (MToN 1 3)
+-- Eval (MToN 1 3) :: [TL.Natural]
 -- = '[1, 2, 3]
 data MToN :: Nat -> Nat -> Exp [Nat]
 type instance Eval (MToN m n) = Eval (Unfoldr (MToNHelp n) m)
@@ -246,8 +240,8 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (ToList 1)
--- Eval (ToList 1) :: [Nat]
+-- > :kind! Eval (ToList 1)
+-- Eval (ToList 1) :: [TL.Natural]
 -- = '[1]
 data ToList :: a -> Exp [a]
 type instance Eval (ToList a) = '[a]
@@ -257,13 +251,12 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Equal '[1,2,3] '[1,2,3])
+-- > :kind! Eval (Equal '[1,2,3] '[1,2,3])
 -- Eval (Equal '[1,2,3] '[1,2,3]) :: Bool
 -- = 'True
 --
--- >>> :kind! Eval (Equal '[1,2,3] '[1,3,2])
+-- > :kind! Eval (Equal '[1,2,3] '[1,3,2])
 -- Eval (Equal '[1,2,3] '[1,3,2]) :: Bool
 -- = 'False
 data Equal :: [a] -> [a] -> Exp Bool
 type instance Eval (Equal as bs) = Eval (And =<< ZipWith TyEq as bs)
-
diff --git a/src/Fcf/Alg/Morphism.hs b/src/Fcf/Alg/Morphism.hs
--- a/src/Fcf/Alg/Morphism.hs
+++ b/src/Fcf/Alg/Morphism.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE DataKinds              #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
 {-# LANGUAGE TypeOperators          #-}
@@ -34,17 +32,8 @@
 
 --------------------------------------------------------------------------------
 
--- For the doctests:
-
--- $setup
--- >>> import qualified GHC.TypeLits as TL
--- >>> import           Fcf.Alg.List
--- >>> import           Fcf.Data.Nat
-
---------------------------------------------------------------------------------
-
 -- | Structure that 'Cata' can fold and that is a result structure of 'Ana'.
-data Fix f = Fix (f (Fix f))
+newtype Fix f = Fix (f (Fix f))
 
 -- | Commonly used name describing the method 'Cata' eats.
 type Algebra f a = f a -> Exp a
@@ -64,22 +53,22 @@
 -- Check Fcf.Alg.List to see example algebras in use. There we have e.g.
 -- ListToFix-function.
 data Cata :: Algebra f a -> Fix f -> Exp a
-type instance Eval (Cata alg ('Fix b)) = alg @@ (Eval (Map (Cata alg) b))
+type instance Eval (Cata alg ('Fix b)) = alg @@ Eval (Map (Cata alg) b)
 
 -- | Ana can also be used to build a 'Fix' structure.
 --
 -- === __Example__
 --
--- >>> data NToOneCoA :: CoAlgebra (ListF Nat) Nat
--- >>> :{
+-- > data NToOneCoA :: CoAlgebra (ListF Nat) Nat
+-- > :{
 --   type instance Eval (NToOneCoA b) =
 --     If (Eval (b < 1) )
 --         'NilF
 --         ('ConsF b ( b TL.- 1))
 -- :}
 --
--- >>> :kind! Eval (Ana NToOneCoA 3)
--- Eval (Ana NToOneCoA 3) :: Fix (ListF Nat)
+-- > :kind! Eval (Ana NToOneCoA 3)
+-- Eval (Ana NToOneCoA 3) :: Fix (ListF TL.Natural)
 -- = 'Fix ('ConsF 3 ('Fix ('ConsF 2 ('Fix ('ConsF 1 ('Fix 'NilF))))))
 data Ana :: CoAlgebra f a -> a -> Exp (Fix f)
 type instance Eval (Ana coalg a) = 'Fix (Eval (Map (Ana coalg) (Eval (coalg a))))
@@ -91,16 +80,16 @@
 --
 -- === __Example__
 --
--- >>> data NToOneCoA :: CoAlgebra (ListF Nat) Nat
--- >>> :{
+-- > data NToOneCoA :: CoAlgebra (ListF Nat) Nat
+-- > :{
 --   type instance Eval (NToOneCoA b) =
 --     If (Eval (b < 1) )
 --         'NilF
 --         ('ConsF b ( b TL.- 1))
 -- :}
 --
--- >>> :kind! Eval (Hylo SumAlg NToOneCoA 5)
--- Eval (Hylo SumAlg NToOneCoA 5) :: Nat
+-- > :kind! Eval (Hylo SumAlg NToOneCoA 5)
+-- Eval (Hylo SumAlg NToOneCoA 5) :: TL.Natural
 -- = 15
 data Hylo :: Algebra f a -> CoAlgebra f b -> b -> Exp a
 type instance Eval (Hylo alg coalg a) = Eval (Cata alg =<< Ana coalg a)
@@ -117,7 +106,7 @@
 -- Check Fcf.Alg.List to see example algebras in use. There we have e.g.
 -- ListToParaFix-function.
 data Para :: RAlgebra f a -> Fix f -> Exp a
-type instance Eval (Para ralg ('Fix  a)) =  ralg @@ (Eval (Map (Fanout ralg) a))
+type instance Eval (Para ralg ('Fix  a)) =  ralg @@ Eval (Map (Fanout ralg) a)
 
 --------------------------------------------------------------------------------
 
@@ -185,8 +174,8 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (First ((+) 1) '(3,"a"))
--- Eval (First ((+) 1) '(3,"a")) :: (Nat, TL.Symbol)
+-- > :kind! Eval (First ((+) 1) '(3,"a"))
+-- Eval (First ((+) 1) '(3,"a")) :: (TL.Natural, TL.Symbol)
 -- = '(4, "a")
 data First :: (a -> Exp b) -> f a c -> Exp (f b c)
 
@@ -201,8 +190,8 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Second ((+) 1) '("a",3))
--- Eval (Second ((+) 1) '("a",3)) :: (TL.Symbol, Nat)
+-- > :kind! Eval (Second ((+) 1) '("a",3))
+-- Eval (Second ((+) 1) '("a",3)) :: (TL.Symbol, TL.Natural)
 -- = '("a", 4)
 data Second :: (c -> Exp d) -> f a c -> Exp (f a d)
 
@@ -212,4 +201,3 @@
 -- Either
 type instance Eval (Second f ('Left a)) = 'Left a
 type instance Eval (Second f ('Right b)) = 'Right (f @@ b)
-
diff --git a/src/Fcf/Alg/Nat.hs b/src/Fcf/Alg/Nat.hs
--- a/src/Fcf/Alg/Nat.hs
+++ b/src/Fcf/Alg/Nat.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE DataKinds              #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
 {-# LANGUAGE TypeOperators          #-}
diff --git a/src/Fcf/Alg/Other.hs b/src/Fcf/Alg/Other.hs
--- a/src/Fcf/Alg/Other.hs
+++ b/src/Fcf/Alg/Other.hs
@@ -1,8 +1,5 @@
-{-# LANGUAGE DataKinds              #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
-{-# LANGUAGE TypeOperators          #-}
 {-# LANGUAGE UndecidableInstances   #-}
 {-# OPTIONS_GHC -Wall                       #-}
 {-# OPTIONS_GHC -Werror=incomplete-patterns #-}
@@ -25,23 +22,17 @@
 
 module Fcf.Alg.Other where
 
-import           Fcf as Fcf
-
---------------------------------------------------------------------------------
-
--- For the doctests:
-
--- $setup
+import           Fcf
 
 --------------------------------------------------------------------------------
 
 -- | Helper.
 --
--- === __Evample__
+-- === __Example__
 --
--- >>> :kind! Eval (PairMaybeToMaybePair '( 'Just "txt", 'Just 1))
+-- > :kind! Eval (PairMaybeToMaybePair '( 'Just "txt", 'Just 1))
 -- Eval (PairMaybeToMaybePair '( 'Just "txt", 'Just 1)) :: Maybe
---                                                           (GHC.Types.Symbol, GHC.Types.Nat)
+--                                                           (Symbol, TL.Natural)
 -- = 'Just '("txt", 1)
 data PairMaybeToMaybePair :: (Maybe a, Maybe b) -> Exp (Maybe (a,b))
 type instance Eval (PairMaybeToMaybePair '( 'Nothing, _)) = 'Nothing
@@ -51,11 +42,10 @@
 
 -- | Id function.
 --
--- === __Evample__
+-- === __Example__
 --
--- >>> :kind! Eval (Id "id")
--- Eval (Id "id") :: GHC.Types.Symbol
+-- > :kind! Eval (Id "id")
+-- Eval (Id "id") :: Symbol
 -- = "id"
 data Id :: a -> Exp a
 type instance Eval (Id a) = a
-
diff --git a/src/Fcf/Alg/Sort.hs b/src/Fcf/Alg/Sort.hs
--- a/src/Fcf/Alg/Sort.hs
+++ b/src/Fcf/Alg/Sort.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE DataKinds              #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
 {-# LANGUAGE TypeOperators          #-}
@@ -22,13 +20,13 @@
 
 module Fcf.Alg.Sort where
 
+import           GHC.TypeLits (Symbol)
 import qualified GHC.TypeLits as TL
 
 import           Fcf ( If, Eval, Exp, type (<=<), type (=<<)
                      , Flip, Not, TyEq, Pure )
 import           Fcf.Data.List ( ZipWith, Filter, type (++) )
 import           Fcf.Data.Nat (Nat)
-import           Fcf.Data.Symbol (Symbol)
 
 --------------------------------------------------------------------------------
 
@@ -38,14 +36,6 @@
 
 --------------------------------------------------------------------------------
 
--- For the doctests:
-
--- $setup
--- >>> import qualified Fcf.Data.Nat as N ( type (<) )
--- >>> import qualified Fcf.Alg.Symbol as S ( type (<) )
-
---------------------------------------------------------------------------------
-
 -- helper for the ListCmp
 data ListCmpFnd :: [Ordering] -> Exp Ordering
 type instance Eval (ListCmpFnd '[]) = 'EQ
@@ -69,7 +59,7 @@
     )
 
 -- | Comparison for the Nats.
--- 
+--
 -- TODO: Would this fit to Fcf.Data.Nat on first-class-families?
 data NatOrd :: Nat -> Nat -> Exp Ordering
 type instance Eval (NatOrd a b) = TL.CmpNat a b
@@ -100,19 +90,19 @@
 -- helper
 data Inord :: Algebra (BTreeF a) [a]
 type instance Eval (Inord 'BEmptyF) = '[]
-type instance Eval (Inord ('BNodeF v l r)) = Eval (l ++ (Eval ('[v] ++ r)))
+type instance Eval (Inord ('BNodeF v l r)) = Eval (l ++ Eval ('[v] ++ r))
 
 
 -- | Qsort - give the comparison function @a -> a -> Exp Bool@ comparing your 
 -- list elements and then Qsort will order the list.
--- 
+--
 -- __Example__
 --
--- >>> :kind! Eval (Qsort (N.<) '[5,3,1,9,4,6,3])
--- Eval (Qsort (N.<) '[5,3,1,9,4,6,3]) :: [Nat]
+-- > :kind! Eval (Qsort (N.<) '[5,3,1,9,4,6,3])
+-- Eval (Qsort (N.<) '[5,3,1,9,4,6,3]) :: [TL.Natural]
 -- = '[1, 3, 3, 4, 5, 6, 9]
 --
--- >>> :kind! Eval (Qsort (S.<) '[ "bb", "e", "a", "e", "d" ])
+-- > :kind! Eval (Qsort (S.<) '[ "bb", "e", "a", "e", "d" ])
 -- Eval (Qsort (S.<) '[ "bb", "e", "a", "e", "d" ]) :: [Symbol]
 -- = '["a", "bb", "d", "e", "e"]
 data Qsort :: (a -> a -> Exp Bool) -> [a] -> Exp [a]
@@ -120,9 +110,7 @@
 
 -- Helper
 --
--- We use the Flip version so that using <-comparison will give an inreasing 
+-- We use the Flip version so that using <-comparison will give an inreasing
 -- Nat-list. Sorting would work without PartCmp.
 data PartCmp :: (a -> a -> Exp Bool) -> CoAlgebra (BTreeF a) [a] 
 type instance Eval (PartCmp cmp coalg) = Eval (PartHlp (Flip cmp) coalg)
-
-
diff --git a/src/Fcf/Alg/Symbol.hs b/src/Fcf/Alg/Symbol.hs
--- a/src/Fcf/Alg/Symbol.hs
+++ b/src/Fcf/Alg/Symbol.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE DataKinds              #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
 {-# LANGUAGE TypeOperators          #-}
@@ -56,7 +54,7 @@
 
 --------------------------------------------------------------------------------
 
--- import           GHC.TypeLits (Symbol)
+import           GHC.TypeLits (Symbol)
 import qualified GHC.TypeLits as TL
 
 import           Fcf.Core (Eval, Exp)
@@ -73,7 +71,7 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Append "hmm" " ok")
+-- > :kind! Eval (Append "hmm" " ok")
 -- Eval (Append "hmm" " ok") :: Symbol
 -- = "hmm ok"
 data Append :: Symbol -> Symbol -> Exp Symbol
@@ -84,15 +82,15 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Intercalate "+" '["aa", "bb", "cc"])
+-- > :kind! Eval (Intercalate "+" '["aa", "bb", "cc"])
 -- Eval (Intercalate "+" '["aa", "bb", "cc"]) :: Symbol
 -- = "aa+bb+cc"
 --
--- >>> :kind! Eval (Intercalate "+" '["aa"])
+-- > :kind! Eval (Intercalate "+" '["aa"])
 -- Eval (Intercalate "+" '["aa"]) :: Symbol
 -- = "aa"
 --
--- >>> :kind! Eval (Intercalate "+" '[])
+-- > :kind! Eval (Intercalate "+" '[])
 -- Eval (Intercalate "+" '[]) :: Symbol
 -- = ""
 data Intercalate :: Symbol -> [Symbol] -> Exp Symbol
@@ -109,11 +107,11 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (IsSpace "a")
+-- > :kind! Eval (IsSpace "a")
 -- Eval (IsSpace "a") :: Bool
 -- = 'False
 --
--- >>> :kind! Eval (IsSpace " ")
+-- > :kind! Eval (IsSpace " ")
 -- Eval (IsSpace " ") :: Bool
 -- = 'True
 data IsSpace :: Symbol -> Exp Bool
@@ -124,11 +122,11 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (IsNewLine "a")
+-- > :kind! Eval (IsNewLine "a")
 -- Eval (IsNewLine "a") :: Bool
 -- = 'False
 --
--- >>> :kind! Eval (IsNewLine "\n")
+-- > :kind! Eval (IsNewLine "\n")
 -- Eval (IsNewLine "\n") :: Bool
 -- = 'True
 data IsNewLine :: Symbol -> Exp Bool
@@ -139,11 +137,11 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (IsTab "a")
+-- > :kind! Eval (IsTab "a")
 -- Eval (IsTab "a") :: Bool
 -- = 'False
 --
--- >>> :kind! Eval (IsTab "\t")
+-- > :kind! Eval (IsTab "\t")
 -- Eval (IsTab "\t") :: Bool
 -- = 'True
 data IsTab :: Symbol -> Exp Bool
@@ -154,27 +152,27 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (IsSpaceDelim "a")
+-- > :kind! Eval (IsSpaceDelim "a")
 -- Eval (IsSpaceDelim "a") :: Bool
 -- = 'False
 --
--- >>> :kind! Eval (IsSpaceDelim "\n")
+-- > :kind! Eval (IsSpaceDelim "\n")
 -- Eval (IsSpaceDelim "\n") :: Bool
 -- = 'True
 data IsSpaceDelim :: Symbol -> Exp Bool
 type instance Eval (IsSpaceDelim s) =
-    Eval (Eval (IsSpace s) || (Eval (Eval (IsNewLine s) || Eval (IsTab s))))
+    Eval (Eval (IsSpace s) || Eval (Eval (IsNewLine s) || Eval (IsTab s)))
 
 
 -- | IsDigit
 --
 -- === __Example__
 --
--- >>> :kind! Eval (IsDigit "3")
+-- > :kind! Eval (IsDigit "3")
 -- Eval (IsDigit "3") :: Bool
 -- = 'True
 --
--- >>> :kind! Eval (IsDigit "a")
+-- > :kind! Eval (IsDigit "a")
 -- Eval (IsDigit "a") :: Bool
 -- = 'False
 data IsDigit :: Symbol -> Exp Bool
@@ -191,7 +189,7 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (SymbolOrd "a" "b")
+-- > :kind! Eval (SymbolOrd "a" "b")
 -- Eval (SymbolOrd "a" "b") :: Ordering
 -- = 'LT
 data SymbolOrd :: Symbol -> Symbol -> Exp Ordering
@@ -201,10 +199,9 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval ("b" <= "a")
+-- > :kind! Eval ("b" <= "a")
 -- Eval ("b" <= "a") :: Bool
 -- = 'False
---
 data (<=) :: Symbol -> Symbol -> Exp Bool
 type instance Eval ((<=) a b) =
     Eval (Eval (TyEq (TL.CmpSymbol a b) 'LT) || Eval (TyEq (TL.CmpSymbol a b) 'EQ))
@@ -213,7 +210,7 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval ("b" >= "a")
+-- > :kind! Eval ("b" >= "a")
 -- Eval ("b" >= "a") :: Bool
 -- = 'True
 data (>=) :: Symbol -> Symbol -> Exp Bool
@@ -224,7 +221,7 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval ("a" < "b")
+-- > :kind! Eval ("a" < "b")
 -- Eval ("a" < "b") :: Bool
 -- = 'True
 data (<) :: Symbol -> Symbol -> Exp Bool
@@ -234,7 +231,7 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval ("b" > "a")
+-- > :kind! Eval ("b" > "a")
 -- Eval ("b" > "a") :: Bool
 -- = 'True
 data (>) :: Symbol -> Symbol -> Exp Bool
@@ -244,7 +241,7 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval ("b" == "a")
+-- > :kind! Eval ("b" == "a")
 -- Eval ("b" == "a") :: Bool
 -- = 'False
 data (==) :: Symbol -> Symbol -> Exp Bool
diff --git a/src/Fcf/Alg/Tree.hs b/src/Fcf/Alg/Tree.hs
--- a/src/Fcf/Alg/Tree.hs
+++ b/src/Fcf/Alg/Tree.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE DataKinds              #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
 {-# LANGUAGE TypeOperators          #-}
@@ -46,7 +44,7 @@
 
 -- | A function to transform a Tree into fixed structure that can be used
 -- by Cata and Ana.
--- 
+--
 -- See the implementation of 'Size' for an example.
 data TreeToFix :: Tree a -> Exp (Fix (TreeF a))
 type instance Eval (TreeToFix ('Node a '[])) = 'Fix ('NodeF a '[])
@@ -55,38 +53,38 @@
 
 --------------------------------------------------------------------------------
 
--- | Sum the nodes of TreeF containing Nats. 
--- 
+-- | Sum the nodes of TreeF containing Nats.
+--
 -- See the implementation of 'Fib' for an example.
 data SumNodesAlg :: Algebra (TreeF Nat) Nat
 type instance Eval (SumNodesAlg ('NodeF x '[]))       = x
-type instance Eval (SumNodesAlg ('NodeF x (b ': bs))) = x TL.+ (Eval (Sum (b ': bs)))
+type instance Eval (SumNodesAlg ('NodeF x (b ': bs))) = x TL.+ Eval (Sum (b ': bs))
 
 -- | Count the nodes of TreeF. 
--- 
+--
 -- See the 'Size' for an example.
 data CountNodesAlg :: Algebra (TreeF a) Nat
 type instance Eval (CountNodesAlg ('NodeF x '[]))       = 1
-type instance Eval (CountNodesAlg ('NodeF x (b ': bs))) = 1 TL.+ (Eval (Sum (b ': bs)))
+type instance Eval (CountNodesAlg ('NodeF x (b ': bs))) = 1 TL.+ Eval (Sum (b ': bs))
 
 
 -- | Size of the Tree is the number of nodes in it.
--- 
+--
 -- __Example__
 --
 -- Size is defined as @ Cata CountNodesAlg =<< TreeToFix tr @
--- and can be used with the following. 
+-- and can be used with the following.
 --
--- >>> data BuildNode :: Nat -> Exp (Nat,[Nat])
--- >>> :{
+-- > data BuildNode :: Nat -> Exp (Nat,[Nat])
+-- > :{
 --   type instance Eval (BuildNode x) =
 --       If (Eval ((2 TL.* x TL.+ 1) >= 8))
 --           '(x, '[])
 --           '(x, '[ 2 TL.* x, (2 TL.* x) TL.+ 1 ])
 -- :}
 --
--- >>> :kind! Eval (Size =<< UnfoldTree BuildNode 1)
--- Eval (Size =<< UnfoldTree BuildNode 1) :: Nat
+-- > :kind! Eval (Size =<< UnfoldTree BuildNode 1)
+-- Eval (Size =<< UnfoldTree BuildNode 1) :: TL.Natural
 -- = 7
 data Size :: Tree a -> Exp Nat
 type instance Eval (Size tr) = Eval (Cata CountNodesAlg =<< TreeToFix tr)
@@ -113,11 +111,11 @@
 
 
 -- | Fibonaccis with Hylo, not efficient
--- 
+--
 -- __Example__
 --
--- >>> :kind! Eval (FibHylo 10)
--- Eval (FibHylo 10) :: Nat
+-- > :kind! Eval (FibHylo 10)
+-- Eval (FibHylo 10) :: TL.Natural
 -- = 55
 data FibHylo :: Nat -> Exp Nat
 type instance Eval (FibHylo n) = Eval (Hylo SumNodesAlg BuildFibTreeCoA n)
@@ -143,13 +141,15 @@
 type instance Eval (FSum ('NodeF a '[])) = 0
 type instance Eval (FSum ('NodeF a (b ': bs))) = Eval (Sum (b ': bs))
 
+
 -- | Sizes example from Recursion Schemes by example, Tim Williams. This annotes
 -- each node with the size of its subtree.
 --
 -- __Example__
 --
--- >>> :kind! Eval (Sizes =<< Ana BuildNodeCoA 1)
--- Eval (Sizes =<< Ana BuildNodeCoA 1) :: Fix (AnnF (TreeF Nat) Nat)
+-- > :kind! Eval (Sizes =<< Ana BuildNodeCoA 1)
+-- Eval (Sizes =<< Ana BuildNodeCoA 1) :: Fix
+--                                          (AnnF (TreeF TL.Natural) TL.Natural)
 -- = 'Fix
 --     ('AnnF
 --        '( 'NodeF
@@ -169,7 +169,7 @@
 --                             'Fix ('AnnF '( 'NodeF 7 '[], 1))],
 --                        3))],
 --           7))
-type instance Eval (Sizes fx) = Eval (Synthesize ( ( (+) 1) <=< FSum) fx)
+type instance Eval (Sizes fx) = Eval (Synthesize ( (+) 1 <=< FSum) fx)
 data Sizes :: Fix f -> Exp (Ann f Nat)
 
 --------------------------------------------------------------------------------
@@ -203,15 +203,13 @@
 type instance Eval (FibAlgebra ('Succ ('Fix ('AnnF '( 'Succ ('Fix ('AnnF '( _, n))) , m) )))) = Eval (n + m)
 
 -- | Efficient Fibonacci type-level function
--- (from Recursion Schemes by example, Tim Williams). Compare this to 
+-- (from Recursion Schemes by example, Tim Williams). Compare this to
 -- 'FibHylo'.
 --
 -- __Example__
 --
--- >>> :kind! Eval (FibHisto 100)
--- Eval (FibHisto 100) :: Nat
+-- > :kind! Eval (FibHisto 100)
+-- Eval (FibHisto 100) :: TL.Natural
 -- = 354224848179261915075
 data FibHisto :: Nat -> Exp Nat
 type instance Eval (FibHisto n) = Eval (Histo FibAlgebra =<< NatToFix n)
-
-
diff --git a/src/Fcf/Control/Monad.hs b/src/Fcf/Control/Monad.hs
new file mode 100644
--- /dev/null
+++ b/src/Fcf/Control/Monad.hs
@@ -0,0 +1,431 @@
+{-# LANGUAGE RankNTypes             #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{-|
+Module      : Fcf.Control.Monad
+Description : Monad definitions
+Copyright   : (c) gspia 2020-
+License     : BSD
+Maintainer  : gspia
+
+= Fcf.Control.Monad
+
+
+-}
+
+--------------------------------------------------------------------------------
+
+module Fcf.Control.Monad where
+
+import           Data.Functor.Identity
+import           GHC.TypeNats as TN
+
+import           Fcf hiding (type (<*>))
+import           Fcf.Class.Monoid (type (<>), MEmpty)
+import           Fcf.Data.Tuple
+
+--------------------------------------------------------------------------------
+
+-- For the doctests:
+
+-- $setup
+-- >>> import qualified GHC.TypeLits as TL
+-- >>> import qualified Fcf.Combinators as C
+
+--------------------------------------------------------------------------------
+-- Functor instances
+
+type instance Eval (Map f ('Identity a)) = 'Identity (Eval (f a))
+
+--------------------------------------------------------------------------------
+-- Common methods for both Applicative and Monad
+
+
+-- | Return corresponds to the 'return' at Monad
+-- or 'pure' of Applicative.
+--
+--
+-- :kind! Eval (Return 1) :: Maybe Nat
+-- :kind! Eval (Return 1) :: Either Symbol Nat
+data Return :: a -> Exp (m a)
+type instance Eval (Return a) = '[a]
+type instance Eval (Return a) = 'Just a
+type instance Eval (Return a) = 'Right a
+type instance Eval (Return a) = 'Identity a
+type instance Eval (Return a) = '(MEmpty, a)
+type instance Eval (Return a) = '(MEmpty, MEmpty, a)
+type instance Eval (Return a) = '(MEmpty, MEmpty, MEmpty, a)
+
+
+--------------------------------------------------------------------------------
+-- Applicative
+
+-- | (<*>) corresponds to the value level '<*>'. Note that this clashes with
+-- the definition given at Fcf.Combinators.((<*>)).
+--
+-- Applicatives that we define include:
+--
+--  - Identity
+--  - []
+--  - Maybe
+--  - Either
+--  - (,)
+--  - (,,)
+--  - (,,,)
+--
+-- === __Example__
+--
+-- >>> :kind! Eval ('Identity Plus2 <*> 'Identity 5)
+-- Eval ('Identity Plus2 <*> 'Identity 5) :: Identity Natural
+-- = 'Identity 7
+--
+-- >>> :kind! Eval ( (<*>) '[ (Fcf.+) 1, (Fcf.*) 10] '[4,5,6,7])
+-- Eval ( (<*>) '[ (Fcf.+) 1, (Fcf.*) 10] '[4,5,6,7]) :: [Natural]
+-- = '[5, 6, 7, 8, 40, 50, 60, 70]
+-- >>> :kind! Eval ( (<*>) '[ (Fcf.+) 1, (Fcf.*) 10] '[])
+-- Eval ( (<*>) '[ (Fcf.+) 1, (Fcf.*) 10] '[]) :: [Natural]
+-- = '[]
+-- >>> :kind! Eval ( (<*>) '[] '[4,5,6,7])
+-- Eval ( (<*>) '[] '[4,5,6,7]) :: [b]
+-- = '[]
+--
+--
+data (<*>) :: f (a -> Exp b) -> f a -> Exp (f b)
+
+type instance Eval ('Identity f <*> m) = Eval (Map f m)
+
+type instance Eval ('[] <*> _) = '[]
+type instance Eval (_ <*> '[]) = '[]
+type instance Eval ((f ': fs) <*> (a ': as)) =
+    Eval ((++) (Eval (Star_ f (a ': as))) (Eval ((<*>) fs (a ':as))))
+
+-- Maybe
+type instance Eval ('Nothing <*> _) = 'Nothing
+type instance Eval ('Just f <*> m) = Eval (Map f m)
+
+-- Either
+type instance Eval ('Left e <*> _) = 'Left e
+type instance Eval ('Right f <*> m) = Eval (Map f m)
+
+-- | For tuples, the 'Monoid' constraint determines how the first values merge.
+-- For example, 'Symbol's concatenate:
+--
+-- >>> :kind! Eval ('("hello", (Fcf.+) 15) <*> '("world!", 2002))
+-- Eval ('("hello", (Fcf.+) 15) <*> '("world!", 2002)) :: (TL.Symbol,
+--                                                         Natural)
+-- = '("helloworld!", 2017)
+type instance Eval ('(u, f) <*> '(v, x)) = '(u <> v, Eval (f x))
+
+-- ((,,) a b)
+type instance Eval ('(a, b, f) <*> '(a', b', x)) = '(a <> a', b <> b', Eval (f x))
+
+-- ((,,,) a b)
+type instance Eval ('(a, b, c, f) <*> '(a', b', c', x)) = '(a <> a', b <> b', c <> c', Eval (f x))
+
+-- | Type level LiftA2.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (LiftA2 (Fcf.+) '[1,2] '[3,4])
+-- Eval (LiftA2 (Fcf.+) '[1,2] '[3,4]) :: [Natural]
+-- = '[4, 5, 5, 6]
+--
+--
+data LiftA2 :: (a -> b -> Exp c) -> f a -> f b -> Exp (f c)
+type instance Eval (LiftA2 f fa fb) = Eval (Eval (Map (App2 f) fa) <*> fb)
+
+-- | Type level LiftA3.
+--
+-- === __Example__
+-- 
+-- >>> :kind! Eval (LiftA3 Tuple3 '[1,2] '[3,4] '[5,6])
+-- Eval (LiftA3 Tuple3 '[1,2] '[3,4] '[5,6]) :: [(Natural, Natural,
+--                                                Natural)]
+-- = '[ '(1, 3, 5), '(1, 3, 6), '(1, 4, 5), '(1, 4, 6), '(2, 3, 5),
+--      '(2, 3, 6), '(2, 4, 5), '(2, 4, 6)]
+--
+-- >>> :kind! Eval (LiftA3 Tuple3 ('Right 5) ('Right 6) ('Left "fail"))
+-- Eval (LiftA3 Tuple3 ('Right 5) ('Right 6) ('Left "fail")) :: Either
+--                                                                TL.Symbol (Natural, Natural, c)
+-- = 'Left "fail"
+--
+data LiftA3 :: (a -> b -> c -> Exp d) -> f a -> f b -> f c -> Exp (f d)
+type instance Eval (LiftA3 f fa fb fc) = Eval (Eval (Eval (Map (App3 f) fa) <*> fb) <*> fc)
+
+-- | Type level LiftA4.
+data LiftA4 :: (a -> b -> c -> d -> Exp e) -> f a -> f b -> f c -> f d -> Exp (f e)
+type instance Eval (LiftA4 f fa fb fc fd) = Eval (Eval (Eval (Eval (Map (App4 f) fa) <*> fb) <*> fc) <*> fd)
+
+-- | Type level LiftA5.
+data LiftA5 :: (a -> b -> c -> d -> e -> Exp g) -> f a -> f b -> f c -> f d -> f e -> Exp (f g)
+type instance Eval (LiftA5 f fa fb fc fd fe) = Eval (Eval (Eval (Eval (Eval (Map (App5 f) fa) <*> fb) <*> fc) <*> fd) <*> fe)
+
+--------------------------------------------------------------------------------
+-- Monad
+
+
+-- | Type level Bind corresponding to the value level bind '>>=' operator.
+--  Note that name (>>=) clashes with the definition given at
+--  Fcf.Combinators.(>>=). (It doesn't export it yet, though.)
+--
+-- Monads that we define include:
+--
+--  - Identity
+--  - []
+--  - Maybe
+--  - Either
+--  - (,)
+--  - (,,)
+--  - (,,,)
+--
+-- === __Example__
+--
+-- Example: double the length of the input list and increase the numbers at
+-- the same time.
+--
+-- >>> :kind! Eval ('[5,6,7] >>= Plus2M)
+-- Eval ('[5,6,7] >>= Plus2M) :: [Natural]
+-- = '[7, 8, 8, 9, 9, 10]
+--
+--
+-- >>> :kind! Eval (XsPlusYsMonadic '[1,2,3] '[4,5,6])
+-- Eval (XsPlusYsMonadic '[1,2,3] '[4,5,6]) :: [Natural]
+-- = '[5, 6, 7, 6, 7, 8, 7, 8, 9]
+data (>>=) :: m a -> (a -> Exp (m b)) -> Exp (m b)
+
+-- Maybe
+type instance Eval ('Nothing >>= f) = 'Nothing
+type instance Eval ('Just a >>= f) = Eval (f a)
+
+-- Either
+type instance Eval ('Left a >>= _) = 'Left a
+type instance Eval ('Right a >>= f) = Eval (f a)
+
+-- Identity
+type instance Eval ('Identity a >>= f) = Eval (f a)
+
+-- Lists
+type instance Eval ('[] >>= _) = '[]
+type instance Eval ((x ': xs) >>= f) = Eval ((f @@ x) ++  Eval (xs >>= f))
+
+-- (,)
+type instance Eval ('(u, a) >>= k) = Eval ('(u, Id) <*> Eval (k a))
+
+-- (,,)
+type instance Eval ('(u, v, a) >>= k) = Eval ('(u, v, Id) <*> Eval (k a))
+
+-- (,,,)
+type instance Eval ('(u, v, w, a) >>= k) = Eval ('(u, v, w, Id) <*> Eval (k a))
+
+-- | Type level >> 
+--
+-- === __Example__
+--
+--
+-- >>> :kind! Eval ( 'Just 1 >> 'Just 2)
+-- Eval ( 'Just 1 >> 'Just 2) :: Maybe Natural
+-- = 'Just 2
+-- >>> :kind! Eval ( 'Nothing >> 'Just 2)
+-- Eval ( 'Nothing >> 'Just 2) :: Maybe Natural
+-- = 'Nothing
+--
+data (>>) :: m a -> m b -> Exp (m b)
+type instance Eval (m >> k) = Eval (m >>= ConstFn k)
+
+--------------------------------------------------------------------------------
+-- MapM
+
+-- | MapM
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (MapM (ConstFn '[ 'True, 'False]) '["a","b","c"])
+-- Eval (MapM (ConstFn '[ 'True, 'False]) '["a","b","c"]) :: [[Bool]]
+-- = '[ '[ 'True, 'True, 'True], '[ 'True, 'True, 'False],
+--      '[ 'True, 'False, 'True], '[ 'True, 'False, 'False],
+--      '[ 'False, 'True, 'True], '[ 'False, 'True, 'False],
+--      '[ 'False, 'False, 'True], '[ 'False, 'False, 'False]]
+--
+--
+data MapM :: (a -> Exp (m b)) -> t a -> Exp (m (t b))
+type instance Eval (MapM f ta) = Eval (Sequence (Map f @@ ta))
+-- Above one is same as:
+-- type instance Eval (MapM f ta) = Eval (Sequence (Eval (Map f ta)))
+
+
+-- | ForM = Flip MapM
+data ForM :: t a -> (a -> Exp (m b)) -> Exp (m (t b))
+type instance Eval (ForM ta f) = Eval (MapM f ta)
+
+
+--------------------------------------------------------------------------------
+-- FoldlM
+
+-- | FoldlM
+--
+-- === __Example__
+--
+-- >>> import GHC.TypeLits as TL (Symbol, type (-))
+-- >>> data Lambda :: Nat -> Nat -> Exp (Either Symbol Natural)
+-- >>> type instance Eval (Lambda a b) = If (Eval (a >= b)) ('Right (a TL.- b)) ('Left "Nat cannot be negative")
+-- >>> :kind! Eval (FoldlM Lambda 5 '[1,1,1])
+-- Eval (FoldlM Lambda 5 '[1,1,1]) :: Either Symbol Natural
+-- = 'Right 2
+-- >>> :kind! Eval (FoldlM Lambda 5 '[1,4,1])
+-- Eval (FoldlM Lambda 5 '[1,4,1]) :: Either Symbol Natural
+-- = 'Left "Nat cannot be negative"
+--
+data FoldlM :: (b -> a -> Exp (m b)) -> b -> t a -> Exp (m b)
+type instance Eval (FoldlM f z0 xs) = Eval ((Eval (Foldr (FoldlMHelper f) Return xs)) z0)
+
+--------------------------------------------------------------------------------
+-- Traversable
+
+
+-- | Traverse
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Traverse Id '[ '[1,2], '[3,4]])
+-- Eval (Traverse Id '[ '[1,2], '[3,4]]) :: [[Natural]]
+-- = '[ '[1, 3], '[1, 4], '[2, 3], '[2, 4]]
+--
+--
+data Traverse :: (a -> Exp (f b)) -> t a -> Exp (f (t b))
+-- type instance Eval (Traverse f ta) = Eval (SequenceA =<< Map f ta)
+-- Could the above one just be made to work? At the moment, the computation
+-- diverges (we need to give the Traverse instances).
+
+-- []
+type instance Eval (Traverse f lst) =
+    Eval (Foldr (ConsHelper f) (Eval (Return '[])) lst)
+
+-- Maybe
+type instance Eval (Traverse f 'Nothing) = Eval (Return 'Nothing)
+type instance Eval (Traverse f ('Just x)) = Eval (Map (Pure1 'Just) (Eval (f x)))
+
+-- Either
+type instance Eval (Traverse f ('Left e)) = Eval (Return ('Left e))
+type instance Eval (Traverse f ('Right x)) = Eval (Map (Pure1 'Right) (Eval (f x)))
+
+-- ((,) a)
+type instance Eval (Traverse f '(x, y)) = Eval (Map (Tuple2 x) (Eval (f y)))
+
+
+-- | Sequence
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Sequence ('Just ('Right 5)))
+-- Eval (Sequence ('Just ('Right 5))) :: Either a (Maybe Natural)
+-- = 'Right ('Just 5)
+--
+-- >>> :kind! Eval (Sequence '[ 'Just 3, 'Just 5, 'Just 7])
+-- Eval (Sequence '[ 'Just 3, 'Just 5, 'Just 7]) :: Maybe [Natural]
+-- = 'Just '[3, 5, 7]
+--
+-- >>> :kind! Eval (Sequence '[ 'Just 3, 'Nothing, 'Just 7])
+-- Eval (Sequence '[ 'Just 3, 'Nothing, 'Just 7]) :: Maybe [Natural]
+-- = 'Nothing
+--
+-- >>> :kind! Eval (Sequence '[ '[1,2], '[3,4]])
+-- Eval (Sequence '[ '[1,2], '[3,4]]) :: [[Natural]]
+-- = '[ '[1, 3], '[1, 4], '[2, 3], '[2, 4]]
+--
+--
+data Sequence :: t (f a) -> Exp (f (t a))
+type instance Eval (Sequence tfa) = Eval (Traverse Id tfa)
+
+--------------------------------------------------------------------------------
+-- Utility
+
+-- | Id function correspondes to term level 'id'-function.
+data Id :: a -> Exp a
+type instance Eval (Id a) = a
+
+--------------------------------------------------------------------------------
+-- Helper Functions
+
+-- | Needed by LiftA2 instance to partially apply function
+data App2 :: (a -> b -> c) -> a -> Exp (b -> c)
+type instance Eval (App2 f a) = f a
+
+-- | Needed by LiftA3 instance to partially apply function
+data App3 :: (a -> b -> c -> d) -> a -> Exp (b -> Exp (c -> d))
+type instance Eval (App3 f a) = Pure2 f a
+
+-- | Needed by LiftA4 instance to partially apply function
+data App4 :: (a -> b -> c -> d -> e) -> a -> Exp (b -> Exp (c -> Exp (d -> e)))
+type instance Eval (App4 f a) = App3 (f a)
+
+-- | Needed by LiftA5 instance to partially apply function
+data App5 :: (a -> b -> c -> d -> e -> g) -> a -> Exp (b -> Exp (c -> Exp (d -> Exp (e -> g))))
+type instance Eval (App5 f a) = App4 (f a)
+
+-- | Helper for the [] applicative instance.
+data Star_ :: (a -> Exp b) -> f a -> Exp (f b)
+type instance Eval (Star_ _ '[]) = '[]
+type instance Eval (Star_ f (a ': as)) =
+    Eval (f a) ': Eval (Star_ f as)
+
+-- | Helper for 'FoldlM'
+data FoldlMHelper :: (b -> a -> Exp (m b)) -> a -> (b -> Exp (m b)) -> Exp (b -> Exp (m b))
+type instance Eval (FoldlMHelper f a b) = Flip (>>=) b <=< Flip f a
+
+-- | Helper for [] traverse
+data ConsHelper :: (a -> Exp (f b)) -> a -> f [b] -> Exp (f [b])
+type instance Eval (ConsHelper f x ys) = Eval (LiftA2 (Pure2 '(:)) (Eval (f x)) ys)
+-- The following would need an extra import line:
+-- type instance Eval (Cons_f f x ys) = Eval (LiftA2 Cons (Eval (f x)) ys)
+
+
+--------------------------------------------------------------------------------
+-- For Examples
+
+-- | For Applicative documentation example
+data Plus1 :: Nat -> Exp Nat
+type instance Eval (Plus1 n) = n TN.+ 1
+
+-- | For Applicative documentation example
+data Plus2 :: Nat -> Exp Nat
+type instance Eval (Plus2 n) = n TN.+ 2
+
+-- | For the example. Turn an input number to list of two numbers of a bit
+-- larger numbers.
+data Plus2M :: Nat -> Exp [Nat]
+type instance Eval (Plus2M n) = '[n TN.+ 2, n TN.+3]
+
+-- | Part of an example
+data PureXPlusY :: Nat -> Nat -> Exp [Nat]
+type instance Eval (PureXPlusY x y) = Eval (Return ((TN.+) x y))
+
+-- | Part of an example
+data XPlusYs :: Nat -> [Nat] -> Exp [Nat]
+type instance Eval (XPlusYs x ys) = Eval (ys >>= PureXPlusY x)
+
+-- | An example implementing
+--
+-- sumM xs ys = do
+--     x <- xs
+--     y <- ys
+--     return (x + y)
+--
+-- or
+--
+-- sumM xs ys = xs >>= (\x -> ys >>= (\y -> pure (x+y)))
+--
+-- Note the use of helper functions. This is a bit awkward, a type level
+-- lambda would be nice.
+data XsPlusYsMonadic :: [Nat] -> [Nat] -> Exp [Nat]
+type instance Eval (XsPlusYsMonadic xs ys) = Eval (xs >>= Flip XPlusYs ys)
+
+-- data Sumnd :: [Nat] -> [Nat] -> Exp [Nat]
+-- type instance Eval (Sumnd xs ys) = xs >>=
+
+-- data Sum2 :: Nat -> Nat -> Exp Nat
+-- type instance Eval (Sum2 x y) = x TN.+ y
diff --git a/src/Fcf/Data/Bitree.hs b/src/Fcf/Data/Bitree.hs
--- a/src/Fcf/Data/Bitree.hs
+++ b/src/Fcf/Data/Bitree.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE DataKinds              #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
 {-# LANGUAGE TypeOperators          #-}
@@ -26,8 +24,7 @@
 module Fcf.Data.Bitree where
 
 import qualified GHC.TypeLits as TL
-import           Fcf as Fcf
--- import           Fcf.Data.List as Fcf
+import           Fcf
 import           Fcf.Data.Nat as N
 
 --------------------------------------------------------------------------------
@@ -101,7 +98,7 @@
 data Flatten :: Tree a -> Exp [a]
 type instance Eval (Flatten ('Leaf a)) = '[a]
 type instance Eval (Flatten ('Node tr1 a tr2)) =
-    a ': Eval ((Eval (Flatten tr1)) ++ (Eval (Flatten tr2)))
+    a ': Eval (Eval (Flatten tr1) ++ Eval (Flatten tr2))
 
 -- | Get the root node from a 'Tree'.
 data GetRoot :: Tree a -> Exp a
diff --git a/src/Fcf/Data/Char.hs b/src/Fcf/Data/Char.hs
new file mode 100644
--- /dev/null
+++ b/src/Fcf/Data/Char.hs
@@ -0,0 +1,200 @@
+{-# LANGUAGE CPP                    #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{-|
+Module      : Fcf.Data.Char
+Description : Type-level Char data methods
+Copyright   : (c) gspia 2020-
+License     : BSD
+Maintainer  : gspia
+
+= Fcf.Data.Char
+
+-}
+
+--------------------------------------------------------------------------------
+
+module Fcf.Data.Char
+  where
+
+
+-- Version should be larger than 9.2.x. Note the two digit space for the
+-- minor.
+#if __GLASGOW_HASKELL__ >= 902
+
+import qualified GHC.TypeLits as TL
+import           Fcf.Core (Eval, Exp)
+import           Fcf.Data.Bool (type (||))
+import           Fcf.Data.List (Elem)
+import           Fcf.Utils (TyEq)
+
+--------------------------------------------------------------------------------
+
+
+-- For the doctests:
+
+-- $setup
+ 
+--------------------------------------------------------------------------------
+
+-- | IsSpace
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (IsSpace 'a')
+-- Eval (IsSpace 'a') :: Bool
+-- = 'False
+--
+-- >>> :kind! Eval (IsSpace ' ')
+-- Eval (IsSpace ' ') :: Bool
+-- = 'True
+data IsSpace :: Char -> Exp Bool
+type instance Eval (IsSpace s) = Eval (s == ' ')
+
+
+-- | IsNewline
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (IsNewLine 'a')
+-- Eval (IsNewLine 'a') :: Bool
+-- = 'False
+--
+-- >>> :kind! Eval (IsNewLine '\n')
+-- Eval (IsNewLine '\n') :: Bool
+-- = 'True
+data IsNewLine :: Char -> Exp Bool
+type instance Eval (IsNewLine s) = Eval (s == '\n')
+
+
+-- | IsTab
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (IsTab 'a')
+-- Eval (IsTab 'a') :: Bool
+-- = 'False
+--
+-- >>> :kind! Eval (IsTab '\t')
+-- Eval (IsTab '\t') :: Bool
+-- = 'True
+data IsTab :: Char -> Exp Bool
+type instance Eval (IsTab s) = Eval (s == '\t')
+
+
+-- | IsSpaceDelim
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (IsSpaceDelim 'a')
+-- Eval (IsSpaceDelim 'a') :: Bool
+-- = 'False
+--
+-- >>> :kind! Eval (IsSpaceDelim '\n')
+-- Eval (IsSpaceDelim '\n') :: Bool
+-- = 'True
+data IsSpaceDelim :: Char -> Exp Bool
+type instance Eval (IsSpaceDelim s) =
+    Eval (Eval (IsSpace s) || Eval (Eval (IsNewLine s) || Eval (IsTab s)))
+
+
+-- | IsDigit
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (IsDigit '3')
+-- Eval (IsDigit '3') :: Bool
+-- = 'True
+--
+-- >>> :kind! Eval (IsDigit 'a')
+-- Eval (IsDigit 'a') :: Bool
+-- = 'False
+data IsDigit :: Char -> Exp Bool
+type instance Eval (IsDigit s)
+    = Eval (Elem s '[ '0','1','2','3','4','5','6','7','8','9'])
+
+
+--------------------------------------------------------------------------------
+
+
+-- | CharOrd - compare two symbols and give type-level Ordering
+-- ( $ 'LT $, $ 'EQ $ or $ 'GT $ ).
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (CharOrd 'a' 'b')
+-- Eval (CharOrd 'a' 'b') :: Ordering
+-- = 'LT
+data CharOrd :: Char -> Char -> Exp Ordering
+type instance Eval (CharOrd a b) = TL.CmpChar a b
+    
+
+-- | Less-than-or-equal comparison for symbols.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval ('b' <= 'a')
+-- Eval ('b' <= 'a') :: Bool
+-- = 'False
+--
+data (<=) :: Char -> Char -> Exp Bool
+type instance Eval ((<=) a b) =
+    Eval (Eval (TyEq (TL.CmpChar a b) 'LT) || Eval (TyEq (TL.CmpChar a b) 'EQ))
+
+-- | Larger-than-or-equal comparison for symbols.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval ('b' >= 'a')
+-- Eval ('b' >= 'a') :: Bool
+-- = 'True
+data (>=) :: Char -> Char -> Exp Bool
+type instance Eval ((>=) a b) =
+    Eval (Eval (TyEq (TL.CmpChar a b) 'GT) || Eval (TyEq (TL.CmpChar a b) 'EQ))
+
+-- | Less-than comparison for symbols.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval ('a' < 'b')
+-- Eval ('a' < 'b') :: Bool
+-- = 'True
+data (<) :: Char -> Char -> Exp Bool
+type instance Eval ((<) a b) = Eval (TyEq (TL.CmpChar a b) 'LT)
+
+-- | Larger-than comparison for symbols.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval ('b' > 'a')
+-- Eval ('b' > 'a') :: Bool
+-- = 'True
+data (>) :: Char -> Char -> Exp Bool
+type instance Eval ((>) a b) = Eval (TyEq (TL.CmpChar a b) 'GT)
+
+-- | Equality of symbols
+--
+-- === __Example__
+--
+-- >>> :kind! Eval ('b' == 'a')
+-- Eval ('b' == 'a') :: Bool
+-- = 'False
+data (==) :: Char -> Char -> Exp Bool
+type instance Eval ((==) a b) = Eval (TyEq (TL.CmpChar a b) 'EQ)
+
+--------------------------------------------------------------------------------
+
+#else
+
+--------------------------------------------------------------------------------
+
+
+#endif
+
+--------------------------------------------------------------------------------
+
diff --git a/src/Fcf/Data/List/Utils.hs b/src/Fcf/Data/List/Utils.hs
new file mode 100644
--- /dev/null
+++ b/src/Fcf/Data/List/Utils.hs
@@ -0,0 +1,59 @@
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{-|
+Module      : Fcf.Data.List.Utils
+Description : List helpers / utils
+Copyright   : (c) gspia 2023-
+License     : BSD
+Maintainer  : gspia
+
+= Fcf.Data.List.Utils
+
+Some of the following methods would probably have better place at the
+first-class-families library.  That is, polish and make a PR.
+
+-}
+
+--------------------------------------------------------------------------------
+
+module Fcf.Data.List.Utils where
+
+import           Fcf
+import           Fcf.Data.List as Fcf
+
+--------------------------------------------------------------------------------
+
+-- For the doctests:
+
+-- $setup
+-- >>> import qualified GHC.TypeLits as TL
+-- >>> import           Fcf.Data.Nat
+
+--------------------------------------------------------------------------------
+
+-- | Foldl in terms of Foldr.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Foldl (Fcf.-) 10 '[3,2,1])
+-- Eval (Foldl (Fcf.-) 10 '[3,2,1]) :: TL.Natural
+-- = 4
+data Foldl :: (b -> a -> Exp b) -> b -> t a -> Exp b
+type instance Eval (Foldl f b ta) = Eval (Foldr (Flip f) b (Eval (Reverse ta)))
+
+
+-- | Turn Maybe into a list.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (MaybeToList ('Just 1))
+-- Eval (MaybeToList ('Just 1)) :: [TL.Natural]
+-- = '[1]
+data MaybeToList :: Maybe a -> Exp [a]
+type instance Eval (MaybeToList 'Nothing) = '[]
+type instance Eval (MaybeToList ('Just a)) = '[a]
+
diff --git a/src/Fcf/Data/MapC.hs b/src/Fcf/Data/MapC.hs
--- a/src/Fcf/Data/MapC.hs
+++ b/src/Fcf/Data/MapC.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE DataKinds              #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
 {-# LANGUAGE TypeOperators          #-}
@@ -81,7 +79,7 @@
 import           Fcf ( Eval, Exp, Fst, Snd, type (=<<), type (<=<), type (@@)
                      , type (++), Not, If
                      , Pure, TyEq, Length, Uncurry)
-import qualified Fcf as Fcf (Map, Foldr, Filter)
+import qualified Fcf (Map, Foldr, Filter)
 import qualified Fcf.Data.List as L (Elem, Partition)
 
 import           Fcf.Alg.Morphism
@@ -94,42 +92,42 @@
 -- $setup
 -- >>> import           Fcf (type (>=))
 -- >>> import           Fcf.Data.Nat
--- >>> import           Fcf.Alg.Symbol (Symbol,Append)
+-- >>> import           Fcf.Data.Symbol
 
 --------------------------------------------------------------------------------
 
 
 -- | A type corresponding to Map in the containers. We call this MapC because
 -- name Map is reserved to the map-function in Fcf-package.
--- 
+--
 -- The representation is based on type-level lists. Please, do not use
--- that fact but rather use the exposed API. (We hope to change the 
+-- that fact but rather use the exposed API. (We hope to change the
 -- internal data type to balanced tree similar to the one used in containers.
 -- See TODO.md.)
-data MapC k v = MapC [(k,v)]
+newtype MapC k v = MapC [(k,v)]
 
 -- | Empty
--- 
+--
 -- === __Example__
--- 
--- >>> :kind! (Eval Empty :: MapC Nat Symbol)
--- (Eval Empty :: MapC Nat Symbol) :: MapC Nat Symbol
+--
+-- >>> :kind! (Eval Empty :: MapC Nat TL.Symbol)
+-- (Eval Empty :: MapC Nat TL.Symbol) :: MapC TL.Natural TL.Symbol
 -- = 'MapC '[]
 --
 -- >>> :kind! (Eval Empty :: MapC Int String)
 -- (Eval Empty :: MapC Int String) :: MapC Int [Char]
 -- = 'MapC '[]
--- 
+--
 -- See also the other examples in this module.
 data Empty :: Exp (MapC k v)
 type instance Eval Empty = 'MapC '[]
 
 -- | Singleton
--- 
+--
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Singleton 1 "haa")
--- Eval (Singleton 1 "haa") :: MapC Nat Symbol
+-- Eval (Singleton 1 "haa") :: MapC TL.Natural TL.Symbol
 -- = 'MapC '[ '(1, "haa")]
 data Singleton :: k -> v -> Exp (MapC k v)
 type instance Eval (Singleton k v) = 'MapC '[ '(k,v)]
@@ -137,9 +135,10 @@
 -- | Use FromList to construct a MapC from type-level list.
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (FromList '[ '(1,"haa"), '(2,"hoo")])
--- Eval (FromList '[ '(1,"haa"), '(2,"hoo")]) :: MapC Nat Symbol
+-- Eval (FromList '[ '(1,"haa"), '(2,"hoo")]) :: MapC
+--                                                 TL.Natural TL.Symbol
 -- = 'MapC '[ '(1, "haa"), '(2, "hoo")]
 data FromList :: [(k,v)] -> Exp (MapC k v)
 type instance Eval (FromList lst) = 'MapC lst
@@ -149,8 +148,8 @@
 -- === __Example__
 --
 -- >>> :kind! Eval (Insert 3 "hih" =<< FromList '[ '(1,"haa"), '(2,"hoo")])
--- Eval (Insert 3 "hih" =<< FromList '[ '(1,"haa"), '(2,"hoo")]) :: MapC 
---                                                                    Nat Symbol
+-- Eval (Insert 3 "hih" =<< FromList '[ '(1,"haa"), '(2,"hoo")]) :: MapC
+--                                                                    TL.Natural TL.Symbol
 -- = 'MapC '[ '(3, "hih"), '(1, "haa"), '(2, "hoo")]
 data Insert :: k -> v -> MapC k v -> Exp (MapC k v)
 type instance Eval (Insert k v ('MapC lst)) =
@@ -164,18 +163,19 @@
 -- if no old, add
 --
 -- === __Example__
--- 
--- >>> :kind! Eval (InsertWith Append 5 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (InsertWith Append 5 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")]) :: MapC
---                                                                           Nat Symbol
+--
+-- >>> :kind! Eval (InsertWith AppendSymbol 5 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")])
+-- Eval (InsertWith AppendSymbol 5 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")]) :: MapC
+--                                                                                 TL.Natural TL.Symbol
 -- = 'MapC '[ '(5, "xxxa"), '(3, "b")]
 --
--- >>> :kind! Eval (InsertWith Append 7 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (InsertWith Append 7 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")]) :: MapC
---                                                                           Nat Symbol
+-- >>> :kind! Eval (InsertWith AppendSymbol 7 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")])
+-- Eval (InsertWith AppendSymbol 7 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")]) :: MapC
+--                                                                                 TL.Natural TL.Symbol
 -- = 'MapC '[ '(5, "a"), '(3, "b"), '(7, "xxx")]
--- >>> :kind! Eval (InsertWith Append 7 "xxx" =<< Empty)
--- Eval (InsertWith Append 7 "xxx" =<< Empty) :: MapC Nat Symbol
+-- >>> :kind! Eval (InsertWith AppendSymbol 7 "xxx" =<< Empty)
+-- Eval (InsertWith AppendSymbol 7 "xxx" =<< Empty) :: MapC
+--                                                       TL.Natural TL.Symbol
 -- = 'MapC '[ '(7, "xxx")]
 data InsertWith :: (v -> v -> Exp v) -> k -> v -> MapC k v -> Exp (MapC k v)
 type instance Eval (InsertWith f k v ('MapC lst)) =
@@ -192,42 +192,43 @@
 
 
 -- | Delete
--- 
+--
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Delete 5 =<< FromList '[ '(5,"a"), '(3,"b")])
 -- Eval (Delete 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: MapC
---                                                          Nat Symbol
+--                                                          TL.Natural TL.Symbol
 -- = 'MapC '[ '(3, "b")]
 --
 -- >>> :kind! Eval (Delete 7 =<< FromList '[ '(5,"a"), '(3,"b")])
 -- Eval (Delete 7 =<< FromList '[ '(5,"a"), '(3,"b")]) :: MapC
---                                                          Nat Symbol
+--                                                          TL.Natural TL.Symbol
 -- = 'MapC '[ '(5, "a"), '(3, "b")]
 --
 -- >>> :kind! Eval (Delete 7 =<< Empty)
--- Eval (Delete 7 =<< Empty) :: MapC Nat v
+-- Eval (Delete 7 =<< Empty) :: MapC TL.Natural v
 -- = 'MapC '[]
 data Delete :: k -> MapC k v -> Exp (MapC k v)
 type instance Eval (Delete k ('MapC lst)) =
     'MapC (Eval (Fcf.Filter (Not <=< TyEq k <=< Fst) lst))
 
 -- | Adjust
--- 
+--
 -- === __Example__
--- 
--- >>> :kind! Eval (Adjust (Append "new ") 5 =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Adjust (Append "new ") 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: MapC
---                                                                          Nat Symbol
+--
+-- >>> :kind! Eval (Adjust (AppendSymbol "new ") 5 =<< FromList '[ '(5,"a"), '(3,"b")])
+-- Eval (Adjust (AppendSymbol "new ") 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: MapC
+--                                                                                TL.Natural TL.Symbol
 -- = 'MapC '[ '(5, "new a"), '(3, "b")]
 --
--- >>> :kind! Eval (Adjust (Append "new ") 7 =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Adjust (Append "new ") 7 =<< FromList '[ '(5,"a"), '(3,"b")]) :: MapC
---                                                                          Nat Symbol
+-- >>> :kind! Eval (Adjust (AppendSymbol "new ") 7 =<< FromList '[ '(5,"a"), '(3,"b")])
+-- Eval (Adjust (AppendSymbol "new ") 7 =<< FromList '[ '(5,"a"), '(3,"b")]) :: MapC
+--                                                                                TL.Natural TL.Symbol
 -- = 'MapC '[ '(5, "a"), '(3, "b")]
 --
--- >>> :kind! Eval (Adjust (Append "new ") 7 =<< Empty)
--- Eval (Adjust (Append "new ") 7 =<< Empty) :: MapC Nat Symbol
+-- >>> :kind! Eval (Adjust (AppendSymbol "new ") 7 =<< Empty)
+-- Eval (Adjust (AppendSymbol "new ") 7 =<< Empty) :: MapC
+--                                                      TL.Natural TL.Symbol
 -- = 'MapC '[]
 data Adjust :: (v -> Exp v) -> k -> MapC k v -> Exp (MapC k v)
 type instance Eval (Adjust f k ('MapC lst)) =
@@ -244,13 +245,15 @@
 -- | Lookup
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Lookup 5 =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Lookup 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: Maybe Symbol
+-- Eval (Lookup 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: Maybe
+--                                                          TL.Symbol
 -- = 'Just "a"
 --
 -- >>> :kind! Eval (Lookup 7 =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Lookup 7 =<< FromList '[ '(5,"a"), '(3,"b")]) :: Maybe Symbol
+-- Eval (Lookup 7 =<< FromList '[ '(5,"a"), '(3,"b")]) :: Maybe
+--                                                          TL.Symbol
 -- = 'Nothing
 data Lookup :: k -> MapC k v -> Exp (Maybe v)
 type instance Eval (Lookup k ('MapC '[])) = 'Nothing
@@ -263,7 +266,7 @@
 -- | Member
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Member 5 =<< FromList '[ '(5,"a"), '(3,"b")])
 -- Eval (Member 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: Bool
 -- = 'True
@@ -277,7 +280,7 @@
 -- | NotMember
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (NotMember 5 =<< FromList '[ '(5,"a"), '(3,"b")])
 -- Eval (NotMember 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: Bool
 -- = 'False
@@ -291,7 +294,7 @@
 -- | Null
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Null =<< FromList '[ '(5,"a"), '(3,"b")])
 -- Eval (Null =<< FromList '[ '(5,"a"), '(3,"b")]) :: Bool
 -- = 'False
@@ -305,9 +308,9 @@
 -- | Size
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Size =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Size =<< FromList '[ '(5,"a"), '(3,"b")]) :: Nat
+-- Eval (Size =<< FromList '[ '(5,"a"), '(3,"b")]) :: TL.Natural
 -- = 2
 data Size :: MapC k v -> Exp TL.Nat
 type instance Eval (Size ('MapC lst)) = Eval (Length lst)
@@ -315,11 +318,11 @@
 -- | Union
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Union (Eval (FromList '[ '(5,"a"), '(3,"b")])) (Eval (FromList '[ '(5,"A"), '(7,"c")])) )
--- Eval (Union (Eval (FromList '[ '(5,"a"), '(3,"b")])) (Eval (FromList '[ '(5,"A"), '(7,"c")])) ) :: MapC 
---                                                                                                      Nat 
---                                                                                                      Symbol
+-- Eval (Union (Eval (FromList '[ '(5,"a"), '(3,"b")])) (Eval (FromList '[ '(5,"A"), '(7,"c")])) ) :: MapC
+--                                                                                                      TL.Natural
+--                                                                                                      TL.Symbol
 -- = 'MapC '[ '(7, "c"), '(5, "a"), '(3, "b")]
 data Union :: MapC k v -> MapC k v -> Exp (MapC k v)
 type instance Eval (Union ('MapC lst1) ('MapC lst2)) =
@@ -333,13 +336,13 @@
 
 
 -- | Difference
--- 
+--
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Difference (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")])))
--- Eval (Difference (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")]))) :: MapC 
---                                                                                                          Nat 
---                                                                                                          Symbol
+-- Eval (Difference (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")]))) :: MapC
+--                                                                                                          TL.Natural
+--                                                                                                          TL.Symbol
 -- = 'MapC '[ '(3, "a")]
 data Difference :: MapC k v -> MapC k v -> Exp (MapC k v)
 type instance Eval (Difference mp1 mp2) =
@@ -354,11 +357,11 @@
 -- | Intersection
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Intersection (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")])))
--- Eval (Intersection (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")]))) :: MapC 
---                                                                                                            Nat 
---                                                                                                            Symbol
+-- Eval (Intersection (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")]))) :: MapC
+--                                                                                                            TL.Natural
+--                                                                                                            TL.Symbol
 -- = 'MapC '[ '(5, "b")]
 data Intersection :: MapC k v -> MapC k v -> Exp (MapC k v)
 type instance Eval (Intersection mp1 mp2) =
@@ -372,7 +375,7 @@
 -- | Disjoint
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Disjoint (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")])))
 -- Eval (Disjoint (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")]))) :: Bool
 -- = 'False
@@ -388,21 +391,24 @@
     Eval (Null =<< Intersection mp1 mp2)
 
 
--- Map 
+-- | Map
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Fcf.Data.MapC.Map (Append "x") =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Fcf.Data.MapC.Map (Append "x") =<< FromList '[ '(5,"a"), '(3,"b")]) :: MapC Nat Symbol
+-- >>> :kind! Eval (Fcf.Data.MapC.Map (AppendSymbol "x") =<< FromList '[ '(5,"a"), '(3,"b")])
+-- Eval (Fcf.Data.MapC.Map (AppendSymbol "x") =<< FromList '[ '(5,"a"), '(3,"b")]) :: MapC
+--                                                                                      TL.Natural
+--                                                                                      TL.Symbol
 -- = 'MapC '[ '(5, "xa"), '(3, "xb")]
 data Map :: (v -> Exp w) -> MapC k v -> Exp (MapC k w)
 type instance Eval (Map f mp) =
     'MapC (Eval (Fcf.Map (Second f) =<< Assocs mp))
 
--- MapWithKey 
+
+-- | MapWithKey
 --
 -- === __Example__
--- 
+--
 data MapWithKey :: (k -> v -> Exp w) -> MapC k v -> Exp (MapC k w)
 type instance Eval (MapWithKey f mp) =
     'MapC (Eval (Fcf.Map (Second (Uncurry f))
@@ -416,15 +422,15 @@
 
 -- | Foldr
 --
--- Fold the values in the map using the given right-associative binary operator, 
+-- Fold the values in the map using the given right-associative binary operator,
 -- such that 'foldr f z == foldr f z . elems'.
 --
 -- Note: the order of values in MapC is not well defined at the moment.
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Fcf.Data.MapC.Foldr (+) 0  =<< (FromList '[ '(1,1), '(2,2)]))
--- Eval (Fcf.Data.MapC.Foldr (+) 0  =<< (FromList '[ '(1,1), '(2,2)])) :: Nat
+-- Eval (Fcf.Data.MapC.Foldr (+) 0  =<< (FromList '[ '(1,1), '(2,2)])) :: TL.Natural
 -- = 3
 data Foldr :: (v -> w -> Exp w) -> w -> MapC k v -> Exp w
 type instance Eval (Foldr f w mp) = Eval (Fcf.Foldr f w =<< Elems mp)
@@ -433,9 +439,9 @@
 -- | Elems
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Elems =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Elems =<< FromList '[ '(5,"a"), '(3,"b")]) :: [Symbol]
+-- Eval (Elems =<< FromList '[ '(5,"a"), '(3,"b")]) :: [TL.Symbol]
 -- = '["a", "b"]
 -- >>> :kind! Eval (Elems =<< Empty)
 -- Eval (Elems =<< Empty) :: [v]
@@ -446,9 +452,9 @@
 -- | Keys
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Keys =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Keys =<< FromList '[ '(5,"a"), '(3,"b")]) :: [Nat]
+-- Eval (Keys =<< FromList '[ '(5,"a"), '(3,"b")]) :: [TL.Natural]
 -- = '[5, 3]
 -- >>> :kind! Eval (Keys =<< Empty)
 -- Eval (Keys =<< Empty) :: [k]
@@ -459,10 +465,10 @@
 -- | Assocs
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Assocs =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Assocs =<< FromList '[ '(5,"a"), '(3,"b")]) :: [(Nat, 
---                                                        Symbol)]
+-- Eval (Assocs =<< FromList '[ '(5,"a"), '(3,"b")]) :: [(TL.Natural,
+--                                                        TL.Symbol)]
 -- = '[ '(5, "a"), '(3, "b")]
 -- >>> :kind! Eval (Assocs =<< Empty)
 -- Eval (Assocs =<< Empty) :: [(k, v)]
@@ -473,10 +479,10 @@
 -- | ToList
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (ToList =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (ToList =<< FromList '[ '(5,"a"), '(3,"b")]) :: [(Nat, 
---                                                        Symbol)]
+-- Eval (ToList =<< FromList '[ '(5,"a"), '(3,"b")]) :: [(TL.Natural,
+--                                                        TL.Symbol)]
 -- = '[ '(5, "a"), '(3, "b")]
 -- >>> :kind! Eval (ToList =<< Empty)
 -- Eval (ToList =<< Empty) :: [(k, v)]
@@ -487,10 +493,10 @@
 -- | Filter
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Filter ((>=) 35) =<< FromList '[ '(5,50), '(3,30)])
--- Eval (Filter ((>=) 35) =<< FromList '[ '(5,50), '(3,30)]) :: MapC 
---                                                                Nat Nat
+-- Eval (Filter ((>=) 35) =<< FromList '[ '(5,50), '(3,30)]) :: MapC
+--                                                                TL.Natural TL.Natural
 -- = 'MapC '[ '(3, 30)]
 data Filter :: (v -> Exp Bool) -> MapC k v -> Exp (MapC k v)
 type instance Eval (Filter f ('MapC lst)) =
@@ -502,7 +508,7 @@
 --
 -- >>> :kind! Eval (FilterWithKey (>=) =<< FromList '[ '(3,5), '(6,4)])
 -- Eval (FilterWithKey (>=) =<< FromList '[ '(3,5), '(6,4)]) :: MapC
---                                                                Nat Nat
+--                                                                TL.Natural TL.Natural
 -- = 'MapC '[ '(6, 4)]
 data FilterWithKey :: (k -> v -> Exp Bool) -> MapC k v -> Exp (MapC k v)
 type instance Eval (FilterWithKey f ('MapC lst)) =
@@ -511,11 +517,11 @@
 -- | Partition
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Partition ((>=) 35) =<< FromList '[ '(5,50), '(3,30)])
--- Eval (Partition ((>=) 35) =<< FromList '[ '(5,50), '(3,30)]) :: (MapC 
---                                                                    Nat Nat, 
---                                                                  MapC Nat Nat)
+-- Eval (Partition ((>=) 35) =<< FromList '[ '(5,50), '(3,30)]) :: (MapC
+--                                                                    TL.Natural TL.Natural,
+--                                                                  MapC TL.Natural TL.Natural)
 -- = '( 'MapC '[ '(3, 30)], 'MapC '[ '(5, 50)])
 data Partition :: (v -> Exp Bool) -> MapC k v -> Exp (MapC k v, MapC k v)
 type instance Eval (Partition f ('MapC lst)) =
@@ -523,5 +529,4 @@
 
 data PartitionHlp :: ([(k,v)],[(k,v)]) -> Exp (MapC k v, MapC k v)
 type instance Eval (PartitionHlp '(xs,ys)) = '( 'MapC xs, 'MapC ys)
-
 
diff --git a/src/Fcf/Data/NatMap.hs b/src/Fcf/Data/NatMap.hs
--- a/src/Fcf/Data/NatMap.hs
+++ b/src/Fcf/Data/NatMap.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE DataKinds              #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
 {-# LANGUAGE TypeOperators          #-}
@@ -74,7 +72,7 @@
 import           Fcf ( Eval, Exp, Fst, Snd, type (=<<), type (<=<), type (@@)
                      , type (++), Not, If
                      , Pure, TyEq, Length, Uncurry)
-import qualified Fcf as Fcf (Map, Foldr, Filter)
+import qualified Fcf (Map, Foldr, Filter)
 import qualified Fcf.Data.List as L (Elem, Partition)
 
 import           Fcf.Data.Nat
@@ -85,43 +83,44 @@
 -- For the doctests:
 
 -- $setup
+-- >>> import qualified GHC.TypeLits as TL
 -- >>> import           Fcf (type (>=))
 -- >>> import           Fcf.Data.Nat
--- >>> import           Fcf.Alg.Symbol (Symbol,Append)
+-- >>> import           Fcf.Data.Symbol
 
 --------------------------------------------------------------------------------
 
 
 -- | A type corresponding to IntMap in the containers.
--- 
+--
 -- The representation is based on type-level lists. Please, do not use
--- that fact but rather use the exposed API. (We hope to change the 
+-- that fact but rather use the exposed API. (We hope to change the
 -- internal data type to balanced tree similar to the one used in containers.
 -- See TODO.md.)
-data NatMap v = NatMap [(Nat,v)]
+newtype NatMap v = NatMap [(Nat,v)]
 
 -- | Empty
--- 
+--
 -- === __Example__
--- 
--- >>> :kind! (Eval Empty :: NatMap Symbol)
--- (Eval Empty :: NatMap Symbol) :: NatMap Symbol
+--
+-- >>> :kind! (Eval Empty :: NatMap TL.Symbol)
+-- (Eval Empty :: NatMap TL.Symbol) :: NatMap TL.Symbol
 -- = 'NatMap '[]
 --
 -- >>> :kind! (Eval Empty :: NatMap String)
 -- (Eval Empty :: NatMap String) :: NatMap [Char]
 -- = 'NatMap '[]
--- 
+--
 -- See also the other examples in this module.
 data Empty :: Exp (NatMap v)
 type instance Eval Empty = 'NatMap '[]
 
 -- | Singleton
--- 
+--
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Singleton 1 "haa")
--- Eval (Singleton 1 "haa") :: NatMap Symbol
+-- Eval (Singleton 1 "haa") :: NatMap TL.Symbol
 -- = 'NatMap '[ '(1, "haa")]
 data Singleton :: Nat -> v -> Exp (NatMap v)
 type instance Eval (Singleton k v) = 'NatMap '[ '(k,v)]
@@ -129,9 +128,9 @@
 -- | Use FromList to construct a NatMap from type-level list.
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (FromList '[ '(1,"haa"), '(2,"hoo")])
--- Eval (FromList '[ '(1,"haa"), '(2,"hoo")]) :: NatMap Symbol
+-- Eval (FromList '[ '(1,"haa"), '(2,"hoo")]) :: NatMap TL.Symbol
 -- = 'NatMap '[ '(1, "haa"), '(2, "hoo")]
 data FromList :: [(Nat,v)] -> Exp (NatMap v)
 type instance Eval (FromList lst) = 'NatMap lst
@@ -141,8 +140,8 @@
 -- === __Example__
 --
 -- >>> :kind! Eval (Insert 3 "hih" =<< FromList '[ '(1,"haa"), '(2,"hoo")])
--- Eval (Insert 3 "hih" =<< FromList '[ '(1,"haa"), '(2,"hoo")]) :: NatMap 
---                                                                    Symbol
+-- Eval (Insert 3 "hih" =<< FromList '[ '(1,"haa"), '(2,"hoo")]) :: NatMap
+--                                                                    TL.Symbol
 -- = 'NatMap '[ '(3, "hih"), '(1, "haa"), '(2, "hoo")]
 data Insert :: Nat -> v -> NatMap v -> Exp (NatMap v)
 type instance Eval (Insert k v ('NatMap lst)) =
@@ -158,19 +157,20 @@
 -- if no old, add
 --
 -- === __Example__
--- 
--- >>> :kind! Eval (InsertWith Append 5 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (InsertWith Append 5 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")]) :: NatMap
---                                                                           Symbol
+--
+-- >>> :kind! Eval (InsertWith AppendSymbol 5 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")])
+-- Eval (InsertWith AppendSymbol 5 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")]) :: NatMap
+--                                                                                 TL.Symbol
 -- = 'NatMap '[ '(5, "xxxa"), '(3, "b")]
 --
--- >>> :kind! Eval (InsertWith Append 7 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (InsertWith Append 7 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")]) :: NatMap
---                                                                           Symbol
+-- >>> :kind! Eval (InsertWith AppendSymbol 7 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")])
+-- Eval (InsertWith AppendSymbol 7 "xxx" =<< FromList '[ '(5,"a"), '(3,"b")]) :: NatMap
+--                                                                                 TL.Symbol
 -- = 'NatMap '[ '(5, "a"), '(3, "b"), '(7, "xxx")]
 --
--- >>> :kind! Eval (InsertWith Append 7 "xxx" =<< Empty)
--- Eval (InsertWith Append 7 "xxx" =<< Empty) :: NatMap Symbol
+-- >>> :kind! Eval (InsertWith AppendSymbol 7 "xxx" =<< Empty)
+-- Eval (InsertWith AppendSymbol 7 "xxx" =<< Empty) :: NatMap
+--                                                       TL.Symbol
 -- = 'NatMap '[ '(7, "xxx")]
 data InsertWith :: (v -> v -> Exp v) -> Nat -> v -> NatMap v -> Exp (NatMap v)
 type instance Eval (InsertWith f k v ('NatMap lst)) =
@@ -187,17 +187,17 @@
 
 
 -- | Delete
--- 
+--
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Delete 5 =<< FromList '[ '(5,"a"), '(3,"b")])
 -- Eval (Delete 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: NatMap
---                                                          Symbol
+--                                                          TL.Symbol
 -- = 'NatMap '[ '(3, "b")]
 --
 -- >>> :kind! Eval (Delete 7 =<< FromList '[ '(5,"a"), '(3,"b")])
 -- Eval (Delete 7 =<< FromList '[ '(5,"a"), '(3,"b")]) :: NatMap
---                                                          Symbol
+--                                                          TL.Symbol
 -- = 'NatMap '[ '(5, "a"), '(3, "b")]
 --
 -- >>> :kind! Eval (Delete 7 =<< Empty)
@@ -208,21 +208,21 @@
     'NatMap (Eval (Fcf.Filter (Not <=< TyEq k <=< Fst) lst))
 
 -- | Adjust
--- 
+--
 -- === __Example__
--- 
--- >>> :kind! Eval (Adjust (Append "new ") 5 =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Adjust (Append "new ") 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: NatMap
---                                                                          Symbol
+--
+-- >>> :kind! Eval (Adjust (AppendSymbol "new ") 5 =<< FromList '[ '(5,"a"), '(3,"b")])
+-- Eval (Adjust (AppendSymbol "new ") 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: NatMap
+--                                                                                TL.Symbol
 -- = 'NatMap '[ '(5, "new a"), '(3, "b")]
 --
--- >>> :kind! Eval (Adjust (Append "new ") 7 =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Adjust (Append "new ") 7 =<< FromList '[ '(5,"a"), '(3,"b")]) :: NatMap
---                                                                          Symbol
+-- >>> :kind! Eval (Adjust (AppendSymbol "new ") 7 =<< FromList '[ '(5,"a"), '(3,"b")])
+-- Eval (Adjust (AppendSymbol "new ") 7 =<< FromList '[ '(5,"a"), '(3,"b")]) :: NatMap
+--                                                                                TL.Symbol
 -- = 'NatMap '[ '(5, "a"), '(3, "b")]
 --
--- >>> :kind! Eval (Adjust (Append "new ") 7 =<< Empty)
--- Eval (Adjust (Append "new ") 7 =<< Empty) :: NatMap Symbol
+-- >>> :kind! Eval (Adjust (AppendSymbol "new ") 7 =<< Empty)
+-- Eval (Adjust (AppendSymbol "new ") 7 =<< Empty) :: NatMap TL.Symbol
 -- = 'NatMap '[]
 data Adjust :: (v -> Exp v) -> Nat -> NatMap v -> Exp (NatMap v)
 type instance Eval (Adjust f k ('NatMap lst)) =
@@ -239,13 +239,15 @@
 -- | Lookup
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Lookup 5 =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Lookup 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: Maybe Symbol
+-- Eval (Lookup 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: Maybe
+--                                                          TL.Symbol
 -- = 'Just "a"
 --
 -- >>> :kind! Eval (Lookup 7 =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Lookup 7 =<< FromList '[ '(5,"a"), '(3,"b")]) :: Maybe Symbol
+-- Eval (Lookup 7 =<< FromList '[ '(5,"a"), '(3,"b")]) :: Maybe
+--                                                          TL.Symbol
 -- = 'Nothing
 data Lookup :: Nat -> NatMap v -> Exp (Maybe v)
 type instance Eval (Lookup k ('NatMap '[])) = 'Nothing
@@ -258,7 +260,7 @@
 -- | Member
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Member 5 =<< FromList '[ '(5,"a"), '(3,"b")])
 -- Eval (Member 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: Bool
 -- = 'True
@@ -272,7 +274,7 @@
 -- | NotMember
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (NotMember 5 =<< FromList '[ '(5,"a"), '(3,"b")])
 -- Eval (NotMember 5 =<< FromList '[ '(5,"a"), '(3,"b")]) :: Bool
 -- = 'False
@@ -286,7 +288,7 @@
 -- | Null
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Null =<< FromList '[ '(5,"a"), '(3,"b")])
 -- Eval (Null =<< FromList '[ '(5,"a"), '(3,"b")]) :: Bool
 -- = 'False
@@ -300,9 +302,9 @@
 -- | Size
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Size =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Size =<< FromList '[ '(5,"a"), '(3,"b")]) :: Nat
+-- Eval (Size =<< FromList '[ '(5,"a"), '(3,"b")]) :: TL.Natural
 -- = 2
 data Size :: NatMap v -> Exp Nat
 type instance Eval (Size ('NatMap lst)) = Eval (Length lst)
@@ -310,10 +312,10 @@
 -- | Union
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Union (Eval (FromList '[ '(5,"a"), '(3,"b")])) (Eval (FromList '[ '(5,"A"), '(7,"c")])) )
--- Eval (Union (Eval (FromList '[ '(5,"a"), '(3,"b")])) (Eval (FromList '[ '(5,"A"), '(7,"c")])) ) :: NatMap 
---                                                                                                      Symbol
+-- Eval (Union (Eval (FromList '[ '(5,"a"), '(3,"b")])) (Eval (FromList '[ '(5,"A"), '(7,"c")])) ) :: NatMap
+--                                                                                                      TL.Symbol
 -- = 'NatMap '[ '(7, "c"), '(5, "a"), '(3, "b")]
 data Union :: NatMap v -> NatMap v -> Exp (NatMap v)
 type instance Eval (Union ('NatMap lst1) ('NatMap lst2)) =
@@ -327,12 +329,12 @@
 
 
 -- | Difference
--- 
+--
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Difference (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")])))
--- Eval (Difference (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")]))) :: NatMap 
---                                                                                                          Symbol
+-- Eval (Difference (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")]))) :: NatMap
+--                                                                                                          TL.Symbol
 -- = 'NatMap '[ '(3, "a")]
 data Difference :: NatMap v -> NatMap v -> Exp (NatMap v)
 type instance Eval (Difference mp1 mp2) =
@@ -347,10 +349,10 @@
 -- | Intersection
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Intersection (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")])))
--- Eval (Intersection (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")]))) :: NatMap 
---                                                                                                            Symbol
+-- Eval (Intersection (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")]))) :: NatMap
+--                                                                                                            TL.Symbol
 -- = 'NatMap '[ '(5, "b")]
 data Intersection :: NatMap v -> NatMap v -> Exp (NatMap v)
 type instance Eval (Intersection mp1 mp2) =
@@ -364,7 +366,7 @@
 -- | Disjoint
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Disjoint (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")])))
 -- Eval (Disjoint (Eval (FromList '[ '(3,"a"), '(5,"b")])) (Eval (FromList '[ '(5,"B"), '(7,"C")]))) :: Bool
 -- = 'False
@@ -384,9 +386,9 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Fcf.Data.NatMap.Map (Append "x") =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Fcf.Data.NatMap.Map (Append "x") =<< FromList '[ '(5,"a"), '(3,"b")]) :: NatMap 
---                                                                                  Symbol
+-- >>> :kind! Eval (Fcf.Data.NatMap.Map (AppendSymbol "x") =<< FromList '[ '(5,"a"), '(3,"b")])
+-- Eval (Fcf.Data.NatMap.Map (AppendSymbol "x") =<< FromList '[ '(5,"a"), '(3,"b")]) :: NatMap
+--                                                                                        TL.Symbol
 -- = 'NatMap '[ '(5, "xa"), '(3, "xb")]
 data Map :: (v -> Exp w) -> NatMap v -> Exp (NatMap w)
 type instance Eval (Map f mp) =
@@ -395,7 +397,7 @@
 -- | NatMapWithKey
 --
 -- === __Example__
--- 
+--
 data NatMapWithKey :: (Nat -> v -> Exp w) -> NatMap v -> Exp (NatMap w)
 type instance Eval (NatMapWithKey f mp) =
     'NatMap (Eval (Fcf.Map (Second (Uncurry f))
@@ -409,15 +411,15 @@
 
 -- | Foldr
 --
--- Fold the values in the map using the given right-associative binary operator, 
+-- Fold the values in the map using the given right-associative binary operator,
 -- such that 'foldr f z == foldr f z . elems'.
 --
 -- Note: the order of values in NatMap is not well defined at the moment.
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Fcf.Data.NatMap.Foldr (+) 0  =<< (FromList '[ '(1,1), '(2,2)]))
--- Eval (Fcf.Data.NatMap.Foldr (+) 0  =<< (FromList '[ '(1,1), '(2,2)])) :: Nat
+-- Eval (Fcf.Data.NatMap.Foldr (+) 0  =<< (FromList '[ '(1,1), '(2,2)])) :: TL.Natural
 -- = 3
 data Foldr :: (v -> w -> Exp w) -> w -> NatMap v -> Exp w
 type instance Eval (Foldr f w mp) = Eval (Fcf.Foldr f w =<< Elems mp)
@@ -426,9 +428,9 @@
 -- | Elems
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Elems =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Elems =<< FromList '[ '(5,"a"), '(3,"b")]) :: [Symbol]
+-- Eval (Elems =<< FromList '[ '(5,"a"), '(3,"b")]) :: [TL.Symbol]
 -- = '["a", "b"]
 -- >>> :kind! Eval (Elems =<< Empty)
 -- Eval (Elems =<< Empty) :: [v]
@@ -439,12 +441,12 @@
 -- | Keys
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Keys =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Keys =<< FromList '[ '(5,"a"), '(3,"b")]) :: [Nat]
+-- Eval (Keys =<< FromList '[ '(5,"a"), '(3,"b")]) :: [TL.Natural]
 -- = '[5, 3]
 -- >>> :kind! Eval (Keys =<< Empty)
--- Eval (Keys =<< Empty) :: [Nat]
+-- Eval (Keys =<< Empty) :: [TL.Natural]
 -- = '[]
 data Keys :: NatMap v -> Exp [Nat]
 type instance Eval (Keys ('NatMap lst)) = Eval (Fcf.Map Fst lst)
@@ -452,13 +454,13 @@
 -- | Assocs
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Assocs =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (Assocs =<< FromList '[ '(5,"a"), '(3,"b")]) :: [(Nat, 
---                                                        Symbol)]
+-- Eval (Assocs =<< FromList '[ '(5,"a"), '(3,"b")]) :: [(TL.Natural,
+--                                                        TL.Symbol)]
 -- = '[ '(5, "a"), '(3, "b")]
 -- >>> :kind! Eval (Assocs =<< Empty)
--- Eval (Assocs =<< Empty) :: [(Nat, v)]
+-- Eval (Assocs =<< Empty) :: [(TL.Natural, v)]
 -- = '[]
 data Assocs :: NatMap v -> Exp [(Nat,v)]
 type instance Eval (Assocs ('NatMap lst)) = lst
@@ -466,13 +468,13 @@
 -- | ToList
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (ToList =<< FromList '[ '(5,"a"), '(3,"b")])
--- Eval (ToList =<< FromList '[ '(5,"a"), '(3,"b")]) :: [(Nat, 
---                                                        Symbol)]
+-- Eval (ToList =<< FromList '[ '(5,"a"), '(3,"b")]) :: [(TL.Natural,
+--                                                        TL.Symbol)]
 -- = '[ '(5, "a"), '(3, "b")]
 -- >>> :kind! Eval (ToList =<< Empty)
--- Eval (ToList =<< Empty) :: [(Nat, v)]
+-- Eval (ToList =<< Empty) :: [(TL.Natural, v)]
 -- = '[]
 data ToList :: NatMap v -> Exp [(Nat,v)]
 type instance Eval (ToList ('NatMap lst)) = lst
@@ -480,10 +482,10 @@
 -- | Filter
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Filter ((>=) 35) =<< FromList '[ '(5,50), '(3,30)])
--- Eval (Filter ((>=) 35) =<< FromList '[ '(5,50), '(3,30)]) :: NatMap 
---                                                                Nat
+-- Eval (Filter ((>=) 35) =<< FromList '[ '(5,50), '(3,30)]) :: NatMap
+--                                                                TL.Natural
 -- = 'NatMap '[ '(3, 30)]
 data Filter :: (v -> Exp Bool) -> NatMap v -> Exp (NatMap v)
 type instance Eval (Filter f ('NatMap lst)) =
@@ -495,7 +497,7 @@
 --
 -- >>> :kind! Eval (FilterWithKey (>=) =<< FromList '[ '(3,5), '(6,4)])
 -- Eval (FilterWithKey (>=) =<< FromList '[ '(3,5), '(6,4)]) :: NatMap
---                                                                Nat
+--                                                                TL.Natural
 -- = 'NatMap '[ '(6, 4)]
 data FilterWithKey :: (Nat -> v -> Exp Bool) -> NatMap v -> Exp (NatMap v)
 type instance Eval (FilterWithKey f ('NatMap lst)) =
@@ -504,11 +506,11 @@
 -- | Partition
 --
 -- === __Example__
--- 
+--
 -- >>> :kind! Eval (Partition ((>=) 35) =<< FromList '[ '(5,50), '(3,30)])
--- Eval (Partition ((>=) 35) =<< FromList '[ '(5,50), '(3,30)]) :: (NatMap 
---                                                                    Nat, 
---                                                                  NatMap Nat)
+-- Eval (Partition ((>=) 35) =<< FromList '[ '(5,50), '(3,30)]) :: (NatMap
+--                                                                    TL.Natural,
+--                                                                  NatMap TL.Natural)
 -- = '( 'NatMap '[ '(3, 30)], 'NatMap '[ '(5, 50)])
 data Partition :: (v -> Exp Bool) -> NatMap v -> Exp (NatMap v, NatMap v)
 type instance Eval (Partition f ('NatMap lst)) =
@@ -516,5 +518,4 @@
 
 data PartitionHlp :: ([(Nat,v)],[(Nat,v)]) -> Exp (NatMap v, NatMap v)
 type instance Eval (PartitionHlp '(xs,ys)) = '( 'NatMap xs, 'NatMap ys)
-
 
diff --git a/src/Fcf/Data/NewText.hs b/src/Fcf/Data/NewText.hs
new file mode 100644
--- /dev/null
+++ b/src/Fcf/Data/NewText.hs
@@ -0,0 +1,1035 @@
+{-# LANGUAGE CPP                    #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{-|
+Module      : Fcf.Data.NewText
+Description : Type-level Text data structure with methods
+Copyright   : (c) gspia 2020-
+License     : BSD
+Maintainer  : gspia
+
+= Fcf.Data.NewText
+
+We mimick Data.Text but on type level. The current internal representation
+of Fcf.Data.Text is based
+on type level lists.  The current (as of early 2023) implementation of this
+Fcf.Data.Text will be deprecated and replaced with the contents of Fcf.Data.NewText
+later 2023 as newer version GHC become more widespread.
+
+The old version working with 9.0.x or less will be kept at Fcf.Data.OldText for
+some time.  Similarly, the module Fcf.Data.NewText contains the functions
+and definitions for better Text type, which will be taken into use after some time.
+
+The Fcf.Data.NewText will replace Fcf.Data.Text eventually.
+
+-}
+
+--------------------------------------------------------------------------------
+
+module Fcf.Data.NewText
+#if __GLASGOW_HASKELL__ >= 902
+    ( Text (..)
+
+    -- * Creation
+    , Empty
+    , Singleton
+    , FromList
+    , FromSymbolList
+    , FromSymbol
+    , ToList
+    , ToSymbolList
+    , ToCharList
+    , Unpack
+
+    -- * Basic Interface
+    , Null
+    , Length
+    , Append
+    , Cons
+    , ConsSymbol
+    , Snoc
+    , SnocSymbol
+    , Uncons
+    , Unsnoc
+    , Head
+    , Last
+    , Tail
+    , Init
+    , CompareLength
+
+    -- * Transformation
+    , FMap
+    , FMapSymbol
+    , FMapT
+    , Intercalate
+    , Intersperse
+    , IntersperseSymbol
+    , Reverse
+    , Replace
+
+    -- * Special Folds
+    , Concat
+    , ConcatMap
+    , ConcatMapSymbol
+    , ConcatMapCS
+    , Any
+    , AnySymbol
+    , All
+    , AllSymbol
+
+    -- * Substrings
+    , Take
+    , TakeEnd
+    , Drop
+    , DropEnd
+    , TakeWhile
+    , TakeWhileSymbol
+    , TakeWhileEnd
+    , TakeWhileEndSymbol
+    , DropWhile
+    , DropWhileEnd
+    , DropWhileEndSymbol
+    , DropAround
+    , DropAroundSymbol
+    , Strip
+
+    -- * Breaking etc
+    , SplitOn
+    , Split
+    , Lines
+    , Words
+    , Unlines
+    , Unwords
+
+    -- * Predicates
+    , IsPrefixOf
+    , IsSuffixOf
+    , IsInfixOf
+    )
+#endif
+  where
+
+-- Version should be larger than 9.2.x. Note the two digit space for the
+-- minor.
+#if __GLASGOW_HASKELL__ >= 902
+
+import           GHC.TypeLits (Symbol)
+import qualified GHC.TypeLits as TL
+
+import           Fcf ( If, Eval, Exp, type (=<<), type (@@)
+                     , Flip, Pure, IsNothing, Fst, Snd)
+import qualified Fcf.Class.Foldable as F (All, Any)
+import           Fcf.Data.List ( type (++) )
+import qualified Fcf.Data.List as F
+    ( Length, Init, Reverse, Take, Drop, TakeWhile, DropWhile
+    , Intercalate, Intersperse, IsPrefixOf, IsSuffixOf, IsInfixOf, Snoc)
+
+import qualified Fcf.Class.Functor as F ( FMap )
+
+
+import           Fcf.Data.Nat (Nat)
+import qualified Fcf.Data.Symbol as S
+import           Fcf.Data.Tuple (Swap)
+import           Fcf.Alg.Other ( PairMaybeToMaybePair )
+import           Fcf.Alg.Morphism (First,Second)
+-- import           Fcf.Alg.Nat (type (==))
+import qualified Fcf.Alg.Symbol as Sym
+
+--------------------------------------------------------------------------------
+
+
+-- For the doctests:
+
+-- $setup
+-- >>> import           Fcf (type (<=<), Not)
+-- >>> import           Fcf.Data.Char as C
+
+--------------------------------------------------------------------------------
+
+-- | 'Text' is a data structure, that is, a list to hold type-level symbols of
+-- length one.
+data Text = Text Symbol
+
+--------------------------------------------------------------------------------
+
+-- | Empty
+--
+-- === __Example__
+--
+-- >>> :kind! (Eval Empty :: Text)
+-- (Eval Empty :: Text) :: Text
+-- = 'Text ""
+--
+-- See also the other examples in this module.
+data Empty :: Exp Text
+type instance Eval Empty = 'Text ""
+
+-- | Singleton
+--
+-- >>> :kind! Eval (Singleton 'a')
+-- Eval (Singleton 'a') :: Text
+-- = 'Text "a"
+data Singleton :: Char -> Exp Text
+type instance Eval (Singleton c) = Eval (FromSymbol =<< S.CharToSymbol c)
+
+
+-- | FromSymbol
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (FromSymbol "some text")
+-- Eval (FromSymbol "some text") :: Text
+-- = 'Text "some text"
+data FromSymbol :: Symbol -> Exp Text
+type instance Eval (FromSymbol s) = 'Text s
+
+
+-- | Use FromList to construct a Text from type-level list.
+--
+-- === __Example__
+--
+-- :kind! Eval (FromSymbolList '["h", "e", "l", "l", "u", "r", "e", "i"])
+-- Eval (FromSymbolList '["h", "e", "l", "l", "u", "r", "e", "i"]) :: Text
+-- = 'Text "hellurei"
+data FromSymbolList :: [Symbol] -> Exp Text
+type instance Eval (FromSymbolList sym) = Eval (FromSymbol =<< S.Concat sym)
+
+
+data FromList :: [Text] -> Exp Text
+type instance Eval (FromList txt) =
+    Eval (FromSymbol =<< S.Concat =<< F.FMap Unpack txt)
+-- hmm, this is also a Monoid, so we should be able to use Concat
+    
+
+-- | Get the type-level list out of the 'Text'.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (ToSymbolList =<< FromSymbolList '["a", "b"])
+-- Eval (ToSymbolList =<< FromSymbolList '["a", "b"]) :: [Symbol]
+-- = '["a", "b"]
+data ToSymbolList :: Text -> Exp [Symbol]
+type instance Eval (ToSymbolList ('Text sym)) =
+    Eval (F.FMap S.CharToSymbol =<< S.ToCharList sym)
+
+
+
+
+-- | Split text to characters and give them as Char list.
+--
+-- > :kind! Eval (ToCharList =<< FromSymbol "abc")
+-- Eval (ToCharList =<< FromSymbol "abc") :: [Char]
+-- = '['a', 'b', 'c']
+data ToCharList :: Text -> Exp [Char]
+type instance Eval (ToCharList ('Text sym)) = S.ToCharList @@ sym
+
+
+-- | Split text to characters and give them as Text list.
+--
+-- > :kind! Eval (ToList =<< FromSymbol "abc")
+-- Eval (ToList =<< FromSymbol "abc") :: [Text]
+-- = '[ 'Text "a", 'Text "b", 'Text "c"]
+data ToList :: Text -> Exp [Text]
+type instance Eval (ToList txt) =
+    Eval (F.FMap Singleton =<< ToCharList txt)
+
+
+-- | Unpack
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Unpack =<< FromSymbol "word")
+-- Eval (Unpack =<< FromSymbol "word") :: Symbol
+-- = "word"
+data Unpack :: Text -> Exp Symbol
+type instance Eval (Unpack ('Text sym)) = sym
+
+
+
+-- | Null
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Null ('Text "ab"))
+-- Eval (Null ('Text "ab")) :: Bool
+-- = 'False
+--
+-- >>> :kind! Eval (Null =<< Empty)
+-- Eval (Null =<< Empty) :: Bool
+-- = 'True
+data Null :: Text -> Exp Bool
+type instance Eval (Null txt) = Eval
+    (If (Eval (IsNothing =<< NullHelper txt))
+        (Pure 'True)
+        (Pure 'False)
+    )
+
+-- > :kind! Eval (NullHelper =<< (Singleton "koe"))
+-- Eval (NullHelper =<< (Singleton "koe")) :: Maybe
+--                                                      (Char, Text)
+-- = 'Just '('k', 'Text "oe")
+data NullHelper :: Text -> Exp (Maybe (Char, Text))
+type instance Eval (NullHelper ('Text symbol)) =
+    Eval (F.FMap (Second FromSymbol) =<< S.UnconsSymbol symbol)
+
+
+-- | Length
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Length =<< FromSymbol "ab")
+-- Eval (Length =<< FromSymbol "ab") :: TL.Natural
+-- = 2
+data Length :: Text -> Exp Nat
+type instance Eval (Length txt) = Eval (F.Length =<< ToCharList txt)
+
+
+-- | Add a Char to the beginning of a type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Cons 'h' ('Text "aamu"))
+-- Eval (Cons 'h' ('Text "aamu")) :: Text
+-- = 'Text "haamu"
+data Cons :: Char -> Text -> Exp Text
+type instance Eval (Cons c ('Text sym)) =
+    'Text (TL.AppendSymbol (Eval (S.CharToSymbol c)) sym)
+
+
+-- | Add a Symbol to the beginning of a type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (ConsSymbol "h" ('Text "aamu"))
+-- Eval (ConsSymbol "h" ('Text "aamu")) :: Text
+-- = 'Text "haamu"
+data ConsSymbol :: Symbol -> Text -> Exp Text
+type instance Eval (ConsSymbol s ('Text sym)) = 'Text (TL.AppendSymbol s sym)
+
+
+-- | Add a Char to the end of a type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Snoc ('Text "aam") 'u')
+-- Eval (Snoc ('Text "aam") 'u') :: Text
+-- = 'Text "aamu"
+data Snoc :: Text -> Char -> Exp Text
+type instance Eval (Snoc ('Text sym) c) =
+    'Text (TL.AppendSymbol sym (Eval (S.CharToSymbol c)))
+
+-- | Add a Symbol to the end of a type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (SnocSymbol ('Text "aam") "u")
+-- Eval (SnocSymbol ('Text "aam") "u") :: Text
+-- = 'Text "aamu"
+data SnocSymbol :: Text -> Symbol -> Exp Text
+type instance Eval (SnocSymbol ('Text sym) s) = 'Text (TL.AppendSymbol sym s)
+
+
+-- | Append two type-level texts.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Append ('Text "aa") ('Text "mu"))
+-- Eval (Append ('Text "aa") ('Text "mu")) :: Text
+-- = 'Text "aamu"
+data Append :: Text -> Text -> Exp Text
+type instance Eval (Append ('Text s1) ('Text s2)) = 'Text (TL.AppendSymbol s1 s2)
+
+
+-- | Get the first Char from type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Uncons ('Text "haamu"))
+-- Eval (Uncons ('Text "haamu")) :: Maybe (Char, Text)
+-- = 'Just '('h', 'Text "aamu")
+--
+-- >>> :kind! Eval (Uncons ('Text ""))
+-- Eval (Uncons ('Text "")) :: Maybe (Char, Text)
+-- = 'Nothing
+data Uncons :: Text -> Exp (Maybe (Char, Text))
+type instance Eval (Uncons txt) =
+    Eval (PairMaybeToMaybePair '( Eval (Head txt), Eval (Tail txt) ))
+
+
+-- | Get the last Char from type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Unsnoc ('Text "aamun"))
+-- Eval (Unsnoc ('Text "aamun")) :: Maybe (Text, Char)
+-- = 'Just '( 'Text "aamu", 'n')
+--
+-- >>> :kind! Eval (Unsnoc ('Text ""))
+-- Eval (Unsnoc ('Text "")) :: Maybe (Text, Char)
+-- = 'Nothing
+data Unsnoc :: Text -> Exp (Maybe (Text, Char))
+type instance Eval (Unsnoc txt) = 
+    Eval (F.FMap Swap =<< F.FMap (Second Reverse) =<< Uncons =<< Reverse txt)
+
+
+-- | Get the first Char of type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Head ('Text "aamu"))
+-- Eval (Head ('Text "aamu")) :: Maybe Char
+-- = 'Just 'a'
+--
+-- >>> :kind! Eval (Head ('Text ""))
+-- Eval (Head ('Text "")) :: Maybe Char
+-- = 'Nothing
+data Head :: Text -> Exp (Maybe Char)
+type instance Eval (Head ('Text sym)) =
+    Eval (F.FMap Fst =<< S.UnconsSymbol sym)
+
+
+-- | Get the last Char of type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Last ('Text "aamu"))
+-- Eval (Last ('Text "aamu")) :: Maybe Char
+-- = 'Just 'u'
+--
+-- >>> :kind! Eval (Last ('Text ""))
+-- Eval (Last ('Text "")) :: Maybe Char
+-- = 'Nothing
+data Last :: Text -> Exp (Maybe Char)
+type instance Eval (Last txt) = Eval (F.FMap Snd =<< Unsnoc txt)
+
+
+-- | Get the tail of a type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Tail ('Text "haamu"))
+-- Eval (Tail ('Text "haamu")) :: Maybe Text
+-- = 'Just ('Text "aamu")
+--
+-- >>> :kind! Eval (Tail ('Text ""))
+-- Eval (Tail ('Text "")) :: Maybe Text
+-- = 'Nothing
+data Tail :: Text -> Exp (Maybe Text)
+type instance Eval (Tail ('Text sym)) =
+    Eval (F.FMap FromSymbol =<< F.FMap Snd =<< S.UnconsSymbol sym)
+
+
+-- | Take all except the last Char from type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Init ('Text "aamun"))
+-- Eval (Init ('Text "aamun")) :: Maybe Text
+-- = 'Just ('Text "aamu")
+--
+-- >>> :kind! Eval (Init ('Text ""))
+-- Eval (Init ('Text "")) :: Maybe Text
+-- = 'Nothing
+data Init :: Text -> Exp (Maybe Text)
+type instance Eval (Init ('Text sym)) = Eval
+    (F.FMap FromSymbol =<< F.FMap S.ConcatChars =<< F.Init =<< S.ToCharList sym)
+
+
+-- | Compare the length of type-level text to given Nat and give
+-- the Ordering.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (CompareLength ('Text "aamu") 3)
+-- Eval (CompareLength ('Text "aamu") 3) :: Ordering
+-- = 'GT
+data CompareLength :: Text -> Nat -> Exp Ordering
+type instance Eval (CompareLength txt n) = TL.CmpNat (Length @@ txt) n
+
+
+
+-- | FMapSymbol for type-level text.
+--
+-- === __Example__
+--
+-- >>> :{
+-- data IsIsymb :: Symbol -> Exp Bool
+-- type instance Eval (IsIsymb s) = Eval ("i" Sym.== s)
+-- data Isymb2e :: Symbol -> Exp Symbol
+-- type instance Eval (Isymb2e s) = Eval
+--     (If (IsIsymb @@ s)
+--         (Pure "e")
+--         (Pure s)
+--     )
+-- :}
+--
+-- >>> :kind! Eval (FMapSymbol Isymb2e ('Text "imu"))
+-- Eval (FMapSymbol Isymb2e ('Text "imu")) :: Text
+-- = 'Text "emu"
+data FMapSymbol :: (Symbol -> Exp Symbol) -> Text -> Exp Text
+type instance Eval (FMapSymbol f txt) =
+    Eval (FromSymbol =<< S.Concat =<< F.FMap f =<< F.FMap Unpack =<< ToList txt)
+
+
+-- | FMap for type-level text.
+--
+-- === __Example__
+--
+-- >>> :{
+-- data DigitsToX :: Char -> Exp Char
+-- type instance Eval (DigitsToX c) = Eval
+--     (If (IsDigit @@ c)
+--         (Pure 'X')
+--         (Pure c)
+--     )
+-- :}
+--
+-- >>> :kind! Eval (FMap DigitsToX ('Text "Some4text5oh9."))
+-- Eval (FMap DigitsToX ('Text "Some4text5oh9.")) :: Text
+-- = 'Text "SomeXtextXohX."
+data FMap :: (Char -> Exp Char) -> Text -> Exp Text
+type instance Eval (FMap f ('Text sym)) =
+    Eval (FromSymbol =<< S.ConcatChars =<< F.FMap f =<< S.ToCharList sym)
+
+
+data FMapT :: (Text -> Exp Text) -> Text -> Exp Text
+type instance Eval (FMapT f txt) = Eval
+    (FromList =<< F.FMap f =<< ToList txt)
+-- is this too much
+
+
+-- | Intercalate for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Intercalate ('Text " & ") ('[ 'Text "aamu", 'Text "valo"]))
+-- Eval (Intercalate ('Text " & ") ('[ 'Text "aamu", 'Text "valo"])) :: Text
+-- = 'Text "aamu & valo"
+data Intercalate :: Text -> [Text] -> Exp Text
+type instance Eval (Intercalate txt txts) = 
+    Eval (FromList =<< F.Intercalate '[txt] =<< F.FMap ToList txts)
+
+
+-- | Intersperse Char for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Intersperse '.' ('Text "aamu"))
+-- Eval (Intersperse '.' ('Text "aamu")) :: Text
+-- = 'Text "a.a.m.u"
+data Intersperse :: Char  -> Text -> Exp Text
+type instance Eval (Intersperse c ('Text sym)) = Eval
+    (FromSymbolList =<< F.Intersperse (S.CharToSymbol @@c) =<< F.FMap S.CharToSymbol =<< S.ToCharList sym)
+
+-- | Intersperse Symbol for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (IntersperseSymbol "." ('Text "aamu"))
+-- Eval (IntersperseSymbol "." ('Text "aamu")) :: Text
+-- = 'Text "a.a.m.u"
+data IntersperseSymbol :: Symbol -> Text -> Exp Text
+type instance Eval (IntersperseSymbol s ('Text sym)) = Eval
+    (FromSymbolList =<< F.Intersperse s =<< F.FMap S.CharToSymbol =<< S.ToCharList sym)
+
+
+-- | Reverse for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Reverse ('Text "aamu"))
+-- Eval (Reverse ('Text "aamu")) :: Text
+-- = 'Text "umaa"
+--
+-- >>> :kind! Eval (Reverse =<< Reverse ('Text "aamu"))
+-- Eval (Reverse =<< Reverse ('Text "aamu")) :: Text
+-- = 'Text "aamu"
+data Reverse :: Text -> Exp Text
+type instance Eval (Reverse ('Text sym)) =
+    Eval (FromSymbol =<< S.ConcatChars =<< F.Reverse =<< S.ToCharList sym)
+
+    
+-- | Replace for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Replace ('Text "tu") ('Text "la") ('Text "tuututtaa"))
+-- Eval (Replace ('Text "tu") ('Text "la") ('Text "tuututtaa")) :: Text
+-- = 'Text "laulattaa"
+data Replace :: Text -> Text -> Text -> Exp Text
+type instance Eval (Replace orig new txt) =
+    Eval (Intercalate new =<< SplitOn orig txt)
+
+
+-- | Concat for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Concat '[ 'Text "la", 'Text "kana"])
+-- Eval (Concat '[ 'Text "la", 'Text "kana"]) :: Text
+-- = 'Text "lakana"
+data Concat :: [Text] -> Exp Text
+type instance Eval (Concat lst) = Eval (FromSymbol =<< S.Concat =<< F.FMap Unpack lst)
+
+
+-- | FConcatMapSymbol for type-level text. This takes Symbol to Text function.
+--
+-- === __Example__
+--
+-- >>> :{
+-- data IsIsymb :: Symbol -> Exp Bool
+-- type instance Eval (IsIsymb s) = Eval ("i" Sym.== s)
+-- data Isymb2aa :: Symbol -> Exp Text
+-- type instance Eval (Isymb2aa s) = Eval
+--     (If (IsIsymb @@ s)
+--         (Pure ('Text "aa"))
+--         (Pure ('Text s))
+--     )
+-- :}
+--
+-- >>> :kind! Eval (ConcatMapSymbol Isymb2aa ('Text "imu ih"))
+-- Eval (ConcatMapSymbol Isymb2aa ('Text "imu ih")) :: Text
+-- = 'Text "aamu aah"
+data ConcatMapSymbol :: (Symbol -> Exp Text) -> Text -> Exp Text
+type instance Eval (ConcatMapSymbol f ('Text sym)) =
+    Eval (Concat =<< F.FMap f =<< F.FMap S.CharToSymbol =<< S.ToCharList sym)
+
+
+-- | ConcatMap for type-level text.  This takes Char to Text function.
+--
+-- === __Example__
+--
+-- >>> :{
+-- data DigitsToHoo :: Char -> Exp Text
+-- type instance Eval (DigitsToHoo c) = Eval
+--     (If (IsDigit @@ c)
+--         (Pure ( 'Text "hoo"))
+--         (Singleton c)
+--     )
+-- :}
+--
+-- >>> :kind! Eval (ConcatMap DigitsToHoo ('Text "haa2hui2"))
+-- Eval (ConcatMap DigitsToHoo ('Text "haa2hui2")) :: Text
+-- = 'Text "haahoohuihoo"
+data ConcatMap :: (Char -> Exp Text) -> Text -> Exp Text
+type instance Eval (ConcatMap f ('Text sym)) =
+    Eval (Concat =<< F.FMap f =<< S.ToCharList sym)
+
+-- | ConcatMap for type-level text.  This takes Char to Symbol function.
+data ConcatMapCS :: (Char -> Exp Symbol) -> Text -> Exp Text
+type instance Eval (ConcatMapCS f ('Text sym)) =
+    Eval (FromSymbol =<< S.Concat =<< F.FMap f =<< S.ToCharList sym)
+
+
+-- | Any for type-level text.  This takes Char to Bool function.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Any IsDigit ('Text "aamu1"))
+-- Eval (Any IsDigit ('Text "aamu1")) :: Bool
+-- = 'True
+--
+-- >>> :kind! Eval (Any IsDigit ('Text "aamu"))
+-- Eval (Any IsDigit ('Text "aamu")) :: Bool
+-- = 'False
+data Any :: (Char -> Exp Bool) -> Text -> Exp Bool
+type instance Eval (Any f ('Text sym)) = Eval (F.Any f =<< S.ToCharList sym)
+
+
+-- | AnySymbol for type-level text.  This takes Symbol to Bool function.
+-- Note that the given function needs to be compatible... (i.e. operating
+-- with symbols of length 1.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (AnySymbol Sym.IsDigit ('Text "aamu1"))
+-- Eval (AnySymbol Sym.IsDigit ('Text "aamu1")) :: Bool
+-- = 'True
+--
+-- >>> :kind! Eval (AnySymbol Sym.IsDigit ('Text "aamu"))
+-- Eval (AnySymbol Sym.IsDigit ('Text "aamu")) :: Bool
+-- = 'False
+data AnySymbol :: (Symbol -> Exp Bool) -> Text -> Exp Bool
+type instance Eval (AnySymbol f ('Text sym)) =
+    Eval (F.Any f =<< F.FMap S.CharToSymbol =<< S.ToCharList sym)
+
+
+-- | All for type-level text. This takes Char to Bool function.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (All IsDigit ('Text "aamu1"))
+-- Eval (All IsDigit ('Text "aamu1")) :: Bool
+-- = 'False
+--
+-- >>> :kind! Eval (All IsDigit ('Text "321"))
+-- Eval (All IsDigit ('Text "321")) :: Bool
+-- = 'True
+data All :: (Char -> Exp Bool) -> Text -> Exp Bool
+type instance Eval (All f ('Text sym)) = Eval (F.All f =<< S.ToCharList sym)
+
+
+-- | AllSymbol for type-level text. This takes Symbol to Bool function.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (AllSymbol Sym.IsDigit ('Text "aamu1"))
+-- Eval (AllSymbol Sym.IsDigit ('Text "aamu1")) :: Bool
+-- = 'False
+--
+-- >>> :kind! Eval (AllSymbol Sym.IsDigit ('Text "321"))
+-- Eval (AllSymbol Sym.IsDigit ('Text "321")) :: Bool
+-- = 'True
+data AllSymbol :: (Symbol -> Exp Bool) -> Text -> Exp Bool
+type instance Eval (AllSymbol f ('Text sym)) =
+    Eval (F.All f =<< F.FMap S.CharToSymbol =<< S.ToCharList sym)
+
+
+-- | Take for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Take 4 ('Text "aamun"))
+-- Eval (Take 4 ('Text "aamun")) :: Text
+-- = 'Text "aamu"
+data Take :: Nat -> Text -> Exp Text
+type instance Eval (Take n txt) = Eval (FromList =<< F.Take n =<< ToList txt)
+
+-- | TakeEnd for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (TakeEnd 4 ('Text "haamu"))
+-- Eval (TakeEnd 4 ('Text "haamu")) :: Text
+-- = 'Text "aamu"
+data TakeEnd :: Nat -> Text -> Exp Text
+type instance Eval (TakeEnd n txt) =
+    Eval (FromList =<< F.Reverse =<< F.Take n =<< F.Reverse =<< ToList txt)
+
+
+-- | Drop for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Drop 2 ('Text "aamuna"))
+-- Eval (Drop 2 ('Text "aamuna")) :: Text
+-- = 'Text "muna"
+data Drop :: Nat -> Text -> Exp Text
+type instance Eval (Drop n txt) = Eval (FromList =<< F.Drop n =<< ToList txt)
+
+
+-- | DropEnd for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (DropEnd 2 ('Text "aamuna"))
+-- Eval (DropEnd 2 ('Text "aamuna")) :: Text
+-- = 'Text "aamu"
+data DropEnd :: Nat -> Text -> Exp Text
+type instance Eval (DropEnd n txt) =
+    Eval (FromList =<< F.Reverse =<< F.Drop n =<< F.Reverse =<< ToList txt)
+
+-- | TakeWhile for type-level text. This takes Char to Bool function.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (TakeWhile (Not <=< IsDigit) ('Text "aamu12"))
+-- Eval (TakeWhile (Not <=< IsDigit) ('Text "aamu12")) :: Text
+-- = 'Text "aamu"
+data TakeWhile :: (Char -> Exp Bool) -> Text -> Exp Text
+type instance Eval (TakeWhile f ('Text sym)) =
+    Eval (FromSymbol =<< S.ConcatChars =<< F.TakeWhile f =<< S.ToCharList sym)
+
+
+-- | TakeWhileSymbol for type-level text. This takes Symbol to Bool function.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (TakeWhileSymbol (Not <=< Sym.IsDigit) ('Text "aamu12"))
+-- Eval (TakeWhileSymbol (Not <=< Sym.IsDigit) ('Text "aamu12")) :: Text
+-- = 'Text "aamu"
+data TakeWhileSymbol :: (Symbol -> Exp Bool) -> Text -> Exp Text
+type instance Eval (TakeWhileSymbol f txt) = Eval
+    (FromSymbolList =<< F.TakeWhile f =<< ToSymbolList txt)
+
+
+-- | TakeWhileEnd for type-level text. This takes Char to Bool function.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (TakeWhileEnd (Not <=< IsDigit) ('Text "12aamu"))
+-- Eval (TakeWhileEnd (Not <=< IsDigit) ('Text "12aamu")) :: Text
+-- = 'Text "aamu"
+data TakeWhileEnd :: (Char -> Exp Bool) -> Text -> Exp Text
+type instance Eval (TakeWhileEnd f ('Text sym)) = Eval
+    (FromSymbol
+    =<< S.ConcatChars =<< F.Reverse =<< F.TakeWhile f =<< F.Reverse
+    =<< S.ToCharList sym)
+
+
+-- | TakeWhileEndSymbol for type-level text. This takes Symbol to Bool function.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (TakeWhileEndSymbol (Not <=< Sym.IsDigit) ('Text "12aamu"))
+-- Eval (TakeWhileEndSymbol (Not <=< Sym.IsDigit) ('Text "12aamu")) :: Text
+-- = 'Text "aamu"
+data TakeWhileEndSymbol :: (Symbol -> Exp Bool) -> Text -> Exp Text
+type instance Eval (TakeWhileEndSymbol f txt) = Eval
+    (FromSymbolList =<< F.Reverse =<< F.TakeWhile f =<< F.Reverse =<< ToSymbolList txt)
+
+
+-- | DropWhile for type-level text. This takes Char to Bool function.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (DropWhile IsDigit ('Text "12aamu"))
+-- Eval (DropWhile IsDigit ('Text "12aamu")) :: Text
+-- = 'Text "aamu"
+data DropWhile :: (Char -> Exp Bool) -> Text -> Exp Text
+type instance Eval (DropWhile f ('Text sym)) = Eval
+    (FromSymbol =<< S.ConcatChars =<< F.DropWhile f =<< S.ToCharList sym)
+
+
+-- | DropWhileSymbol for type-level text. This takes Symbol to Bool function.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (DropWhileSymbol Sym.IsDigit ('Text "12aamu"))
+-- Eval (DropWhileSymbol Sym.IsDigit ('Text "12aamu")) :: Text
+-- = 'Text "aamu"
+data DropWhileSymbol :: (Symbol -> Exp Bool) -> Text -> Exp Text
+type instance Eval (DropWhileSymbol f txt) = Eval
+    (FromSymbolList =<< F.DropWhile f =<< ToSymbolList txt)
+
+
+-- | DropWhileEnd for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (DropWhileEnd IsDigit ('Text "aamu12"))
+-- Eval (DropWhileEnd IsDigit ('Text "aamu12")) :: Text
+-- = 'Text "aamu"
+data DropWhileEnd :: (Char -> Exp Bool) -> Text -> Exp Text
+type instance Eval (DropWhileEnd f ('Text sym)) = Eval
+    (FromSymbol =<< S.ConcatChars  =<< F.Reverse =<< F.DropWhile f
+    =<< F.Reverse =<< S.ToCharList sym)
+
+
+-- | DropWhileEndSymbol for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (DropWhileEndSymbol Sym.IsDigit ('Text "aamu12"))
+-- Eval (DropWhileEndSymbol Sym.IsDigit ('Text "aamu12")) :: Text
+-- = 'Text "aamu"
+data DropWhileEndSymbol :: (Symbol -> Exp Bool) -> Text -> Exp Text
+type instance Eval (DropWhileEndSymbol f txt) = Eval
+    (FromSymbolList =<< F.Reverse =<< F.DropWhile f =<< F.Reverse =<< ToSymbolList txt)
+
+
+-- | DropAround for type-level text. This takes Char to Bool function.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (DropAround IsDigit ('Text "34aamu12"))
+-- Eval (DropAround IsDigit ('Text "34aamu12")) :: Text
+-- = 'Text "aamu"
+data DropAround :: (Char -> Exp Bool) -> Text -> Exp Text
+type instance Eval (DropAround f txt) = Eval (DropWhile f =<< DropWhileEnd f txt)
+
+
+-- | DropAroundSymbol for type-level text. This takes Symbol to Bool function.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (DropAroundSymbol Sym.IsDigit ('Text "34aamu12"))
+-- Eval (DropAroundSymbol Sym.IsDigit ('Text "34aamu12")) :: Text
+-- = 'Text "aamu"
+data DropAroundSymbol :: (Symbol -> Exp Bool) -> Text -> Exp Text
+type instance Eval (DropAroundSymbol f txt) =
+    Eval (DropWhileSymbol f =<< DropWhileEndSymbol f txt)
+
+
+-- | Strip the space, newline and tab -symbols from the beginning and and
+-- of type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Strip ('Text "  aamu \n"))
+-- Eval (Strip ('Text "  aamu \n")) :: Text
+-- = 'Text "aamu"
+data Strip :: Text -> Exp Text
+type instance Eval (Strip txt) = Eval (DropAroundSymbol Sym.IsSpaceDelim txt)
+
+
+-- | SplitOn for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (SplitOn ('Text "ab") ('Text "cdabfgabh"))
+-- Eval (SplitOn ('Text "ab") ('Text "cdabfgabh")) :: [Text]
+-- = '[ 'Text "cd", 'Text "fg", 'Text "h"]
+data SplitOn :: Text -> Text -> Exp [Text]
+type instance Eval (SplitOn ('Text sep) ('Text txt)) = Eval
+    -- (F.FMap FromSymbolList
+    (F.FMap FromSymbol =<< F.FMap S.ConcatChars
+    =<< SOLoop (Eval (S.ToCharList sep)) '( '[], Eval (S.ToCharList txt)))
+
+
+-- | Helper for SplitOn
+--
+-- >>> :kind! Eval (SOTake '[ 'a', 'b'] '[ 'c', 'd', 'a', 'b', 'f', 'g'] '[])
+-- Eval (SOTake '[ 'a', 'b'] '[ 'c', 'd', 'a', 'b', 'f', 'g'] '[]) :: ([Char],
+--                                                                     [Char])
+-- = '( '['c', 'd'], '['f', 'g'])
+data SOTake :: [Char] -> [Char] -> [Char] -> Exp ([Char], [Char])
+type instance Eval (SOTake sep '[] accum) = '(accum, '[])
+type instance Eval (SOTake sep (t ': txt) accum) = Eval
+    (If (Eval (F.IsPrefixOf sep (t ': txt)))
+        (Pure '(accum, Eval (F.Drop (Eval (F.Length sep)) (t ': txt))))
+        (SOTake sep txt (Eval (accum ++ '[t])))
+    )
+
+-- | Helper for SplitOn
+data SOLoop :: [Char] -> ([[Char]],[Char]) -> Exp [[Char]]
+type instance Eval (SOLoop sep '(acc, '[])) = acc
+type instance Eval (SOLoop sep '(acc, (t ': txt))) =
+    Eval (SOLoop sep =<< First (F.Snoc acc) =<< SOTake sep (t ': txt) '[])
+
+
+-- | Split for type-level text. This takes Char to Bool function.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Split C.IsSpace (Eval (FromSymbol "cd bf abh")))
+-- Eval (Split C.IsSpace (Eval (FromSymbol "cd bf abh"))) :: [Text]
+-- = '[ 'Text "cd", 'Text "bf", 'Text "abh"]
+data Split :: (Char -> Exp Bool) -> Text -> Exp [Text]
+type instance Eval (Split p ('Text sym)) = Eval
+    (F.FMap FromSymbol =<< F.FMap S.ConcatChars
+    =<< SplitLoop p '( '[], Eval (S.ToCharList sym)))
+
+
+-- | SplitSymbol for type-level text. This takes Symbol to Bool function.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (SplitSymbol Sym.IsSpace (Eval (FromSymbol "cd bf abh")))
+-- Eval (SplitSymbol Sym.IsSpace (Eval (FromSymbol "cd bf abh"))) :: [Text]
+-- = '[ 'Text "cd", 'Text "bf", 'Text "abh"]
+data SplitSymbol :: (Symbol -> Exp Bool) -> Text -> Exp [Text]
+type instance Eval (SplitSymbol p txt) =
+    Eval (F.FMap FromSymbolList =<< SplitLoop p '( '[], Eval (ToSymbolList txt)))
+
+-- | Helper for Split
+data SplitTake :: (a -> Exp Bool) -> [a] -> [a] -> Exp ([a], [a])
+type instance Eval (SplitTake p '[] accum) = '(accum, '[])
+type instance Eval (SplitTake p (t ': txt) accum) = Eval
+    (If (Eval (p t))
+        (Pure '(accum, txt))
+        (SplitTake p txt (Eval (accum ++ '[t])))
+    )
+
+-- | Helper for Split
+data SplitLoop :: (a -> Exp Bool) -> ([[a]],[a]) -> Exp [[a]]
+type instance Eval (SplitLoop p '(acc, '[])) = acc
+type instance Eval (SplitLoop p '(acc, (t ': txt))) = 
+    Eval (SplitLoop p =<< First (F.Snoc acc) =<< SplitTake p (t ': txt) '[])
+
+
+-- | Lines for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Lines =<< FromSymbol "ok\nhmm\nab")
+-- Eval (Lines =<< FromSymbol "ok\nhmm\nab") :: [Text]
+-- = '[ 'Text "ok", 'Text "hmm", 'Text "ab"]
+data Lines :: Text -> Exp [Text]
+type instance Eval (Lines txt) = Eval (SplitSymbol Sym.IsNewLine txt)
+
+
+-- | Words for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Words =<< FromSymbol "ok hmm\nab")
+-- Eval (Words =<< FromSymbol "ok hmm\nab") :: [Text]
+-- = '[ 'Text "ok", 'Text "hmm", 'Text "ab"]
+data Words :: Text -> Exp [Text]
+type instance Eval (Words txt) = Eval (SplitSymbol Sym.IsSpaceDelim txt)
+
+-- | Unlines for type-level text. This adds a newline to each Text and then
+-- concats them.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Unlines '[ 'Text "ok", 'Text "hmm", 'Text "ab"])
+-- Eval (Unlines '[ 'Text "ok", 'Text "hmm", 'Text "ab"]) :: Text
+-- = 'Text "ok\nhmm\nab\n"
+data Unlines :: [Text] -> Exp Text
+type instance Eval (Unlines txts) = 
+    Eval (Concat =<< F.FMap (Flip Append (FromSymbol @@ "\n")) txts)
+
+-- | Unwords for type-level text. This uses 'Intercalate' to add space-symbol
+-- between the given texts.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Unwords '[ 'Text "ok", 'Text "hmm", 'Text "ab"])
+-- Eval (Unwords '[ 'Text "ok", 'Text "hmm", 'Text "ab"]) :: Text
+-- = 'Text "ok hmm ab"
+data Unwords :: [Text] -> Exp Text
+type instance Eval (Unwords txts) = Eval (Intercalate ('Text " ") txts)
+
+
+-- | IsPrefixOf for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (IsPrefixOf ('Text "aa") ('Text "aamiainen"))
+-- Eval (IsPrefixOf ('Text "aa") ('Text "aamiainen")) :: Bool
+-- = 'True
+data IsPrefixOf :: Text -> Text -> Exp Bool
+type instance Eval (IsPrefixOf l1 l2) =
+    Eval (F.IsPrefixOf (Eval (ToList l1)) (Eval (ToList l2)))
+
+
+-- | IsSuffixOf for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (IsSuffixOf ('Text "nen") ('Text "aamiainen"))
+-- Eval (IsSuffixOf ('Text "nen") ('Text "aamiainen")) :: Bool
+-- = 'True
+data IsSuffixOf :: Text -> Text -> Exp Bool
+type instance Eval (IsSuffixOf l1 l2) =
+    Eval (F.IsSuffixOf (Eval (ToList l1)) (Eval (ToList l2)))
+
+
+-- | IsInfixOf for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (IsInfixOf ('Text "mia") ('Text "aamiainen"))
+-- Eval (IsInfixOf ('Text "mia") ('Text "aamiainen")) :: Bool
+-- = 'True
+data IsInfixOf :: Text -> Text -> Exp Bool
+type instance Eval (IsInfixOf l1 l2) =
+    Eval (F.IsInfixOf (Eval (ToList l1)) (Eval (ToList l2)))
+
+
+--------------------------------------------------------------------------------
+
+#else
+
+--------------------------------------------------------------------------------
+
+#endif
+
+--------------------------------------------------------------------------------
diff --git a/src/Fcf/Data/OldText.hs b/src/Fcf/Data/OldText.hs
new file mode 100644
--- /dev/null
+++ b/src/Fcf/Data/OldText.hs
@@ -0,0 +1,753 @@
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{-|
+Module      : Fcf.Data.OldText
+Description : Type-level Text data structure with methods
+Copyright   : (c) gspia 2020-
+License     : BSD
+Maintainer  : gspia
+
+= Fcf.Data.OldText
+
+We mimick Data.Text but on type level. The internal representation is based on
+type level lists.  This module is for GHC version 9.0.x or less.  The current
+(as of early 2023) implementation of Fcf.Data.Text will be deprecated and replaced
+with the contents of Fcf.Data.NewText later 2023 as newer version GHC become more
+widespread.
+
+-}
+
+--------------------------------------------------------------------------------
+
+module Fcf.Data.OldText
+    {-# DEPRECATED "Use Fcf.Data.NewText instead" #-}
+    ( Text (..)
+
+    -- * Creation
+    , Empty
+    , Singleton
+    , FromList
+    , FromSymbolList
+    , ToList
+    , ToSymbol
+    , ToSymbolList
+
+    -- * Basic Interface
+    , Null
+    , Length
+    , Append
+    , Cons
+    , Snoc
+    , Uncons
+    , Unsnoc
+    , Head
+    , Tail
+    , Init
+    , CompareLength
+
+    -- * Transformation
+    , FMap
+    , Intercalate
+    , Intersperse
+    , Reverse
+    , Replace
+
+    -- * Special Folds
+    , Concat
+    , FConcatMap
+    , Any
+    , All
+
+    -- * Substrings
+    , Take
+    , TakeEnd
+    , Drop
+    , DropEnd
+    , TakeWhile
+    , TakeWhileEnd
+    , DropWhile
+    , DropWhileEnd
+    , DropAround
+    , Strip
+
+    -- * Breaking etc
+    , SplitOn
+    , Split
+    , Lines
+    , Words
+    , Unlines
+    , Unwords
+
+    -- * Predicates
+    , IsPrefixOf
+    , IsSuffixOf
+    , IsInfixOf
+    )
+  where
+
+import           GHC.TypeLits (Symbol)
+import qualified GHC.TypeLits as TL
+
+import           Fcf ( If, Eval, Exp, type (=<<), type (@@)
+                     , Flip, Pure)
+import qualified Fcf.Class.Foldable as F (All, Any)
+import           Fcf.Data.List ( type (++) )
+import qualified Fcf.Data.List as F
+    ( Length, Init, Reverse, Take, Drop, TakeWhile, DropWhile
+    , Intercalate, Intersperse, IsPrefixOf, IsSuffixOf, IsInfixOf, Snoc)
+
+import qualified Fcf.Class.Functor as F ( FMap )
+
+
+import           Fcf.Data.Nat (Nat)
+import qualified Fcf.Data.Text.Internal as T
+import           Fcf.Alg.Other ( PairMaybeToMaybePair )
+import           Fcf.Alg.Morphism (First,Second)
+import qualified Fcf.Alg.Symbol as S
+import           Fcf.Alg.Nat (type (==))
+
+--------------------------------------------------------------------------------
+
+
+-- For the doctests:
+
+-- $setup
+-- >>> import           Fcf (type (<=<), Not)
+
+--------------------------------------------------------------------------------
+
+-- | 'Text' is a data structure, that is, a list to hold type-level symbols of
+-- length one.
+newtype Text = Text Symbol
+
+--------------------------------------------------------------------------------
+
+-- | Empty
+--
+-- === __Example__
+--
+-- >>> :kind! (Eval Empty :: Text)
+-- (Eval Empty :: Text) :: Text
+-- = 'Text ""
+--
+-- See also the other examples in this module.
+data Empty :: Exp Text
+type instance Eval Empty = 'Text ""
+
+-- | Singleton
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Singleton "a")
+-- Eval (Singleton "a") :: Text
+-- = 'Text "a"
+data Singleton :: Symbol -> Exp Text
+type instance Eval (Singleton s) = 'Text s
+
+
+
+-- | Use FromList to construct a Text from type-level list.
+--
+-- === __Example__
+--
+-- :kind! Eval (FromSymbolList '["h", "e", "l", "l", "u", "r", "e", "i"])
+-- Eval (FromSymbolList '["h", "e", "l", "l", "u", "r", "e", "i"]) :: Text
+-- = 'Text "hellurei"
+data FromSymbolList :: [Symbol] -> Exp Text
+type instance Eval (FromSymbolList sym) =  'Text (T.ToSymbol2 @@ sym)
+
+
+-- hmm, this is also a Monoid, so we should be able to use Concat
+data FromList :: [Text] -> Exp Text
+type instance Eval (FromList txt) =
+    'Text (T.ToSymbol2 @@ Eval (F.FMap ToSymbol txt))
+
+-- | Get the type-level list out of the 'Text'.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (ToSymbolList =<< FromSymbolList '["a", "b"])
+-- Eval (ToSymbolList =<< FromSymbolList '["a", "b"]) :: [Symbol]
+-- = '["a", "b"]
+data ToSymbolList :: Text -> Exp [Symbol]
+type instance Eval (ToSymbolList ('Text sym)) = T.ToListA @@ sym
+
+
+-- | Split 'Text' to single character 'Text' list.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (ToList =<< FromSymbolList '["a", "b"])
+-- Eval (ToList =<< FromSymbolList '["a", "b"]) :: [Text]
+-- = '[ 'Text "a", 'Text "b"]
+data ToList :: Text -> Exp [Text]
+type instance Eval (ToList txt) = Eval (F.FMap Singleton =<< ToSymbolList txt)
+
+
+-- | ToSymbol
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (ToSymbol =<< FromSymbolList '["w", "o", "r", "d"])
+-- Eval (ToSymbol =<< FromSymbolList '["w", "o", "r", "d"]) :: Symbol
+-- = "word"
+data ToSymbol :: Text -> Exp Symbol
+type instance Eval (ToSymbol ('Text sym)) = sym
+
+
+
+-- | Null
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Null ('Text "ab"))
+-- Eval (Null ('Text "ab")) :: Bool
+-- = 'False
+--
+-- >>> :kind! Eval (Null =<< Empty)
+-- Eval (Null =<< Empty) :: Bool
+-- = 'True
+data Null :: Text -> Exp Bool
+type instance Eval (Null txt) = Eval
+    (If (Eval (Eval (Length txt) == 0))
+        (Pure 'True)
+        (Pure 'False)
+    )
+
+
+-- | Length
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Length =<< Singleton "ab")
+-- Eval (Length =<< Singleton "ab") :: TL.Natural
+-- = 2
+data Length :: Text -> Exp Nat
+type instance Eval (Length ('Text sym)) = Eval (F.Length (T.ToList sym))
+
+
+-- | Add a symbol to the beginning of a type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Cons "h" ('Text "aamu"))
+-- Eval (Cons "h" ('Text "aamu")) :: Text
+-- = 'Text "haamu"
+data Cons :: Symbol -> Text -> Exp Text
+type instance Eval (Cons s ('Text sym)) = 'Text (TL.AppendSymbol s sym)
+
+-- | Add a symbol to the end of a type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Snoc ('Text "aam") "u")
+-- Eval (Snoc ('Text "aam") "u") :: Text
+-- = 'Text "aamu"
+data Snoc :: Text -> Symbol -> Exp Text
+type instance Eval (Snoc ('Text sym) s) = 'Text (TL.AppendSymbol sym s)
+
+-- | Append two type-level texts.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Append ('Text "aa") ('Text "mu"))
+-- Eval (Append ('Text "aa") ('Text "mu")) :: Text
+-- = 'Text "aamu"
+data Append :: Text -> Text -> Exp Text
+type instance Eval (Append ('Text s1) ('Text s2)) = 'Text (TL.AppendSymbol s1 s2)
+
+
+-- | Get the first symbol from type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Uncons ('Text "haamu"))
+-- Eval (Uncons ('Text "haamu")) :: Maybe (Symbol, Text)
+-- = 'Just '("h", 'Text "aamu")
+--
+-- >>> :kind! Eval (Uncons ('Text ""))
+-- Eval (Uncons ('Text "")) :: Maybe (Symbol, Text)
+-- = 'Nothing
+data Uncons :: Text -> Exp (Maybe (TL.Symbol, Text))
+type instance Eval (Uncons txt) =
+    Eval (PairMaybeToMaybePair '( Eval (Head txt), Eval (Tail txt) ))
+
+
+
+
+-- | Get the last symbol from type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Unsnoc ('Text "aamun"))
+-- Eval (Unsnoc ('Text "aamun")) :: Maybe (Symbol, Text)
+-- = 'Just '("n", 'Text "aamu")
+--
+-- >>> :kind! Eval (Unsnoc ('Text ""))
+-- Eval (Unsnoc ('Text "")) :: Maybe (Symbol, Text)
+-- = 'Nothing
+data Unsnoc :: Text -> Exp (Maybe (Symbol, Text))
+type instance Eval (Unsnoc txt) = 
+    Eval (F.FMap (Second Reverse) =<< Uncons =<< Reverse txt)
+
+
+-- | Get the first symbol of type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Head ('Text "aamu"))
+-- Eval (Head ('Text "aamu")) :: Maybe Symbol
+-- = 'Just "a"
+--
+-- >>> :kind! Eval (Head ('Text ""))
+-- Eval (Head ('Text "")) :: Maybe Symbol
+-- = 'Nothing
+data Head :: Text -> Exp (Maybe Symbol)
+type instance Eval (Head ('Text sym)) = Eval
+    (If (Eval (Eval (Length ('Text sym)) == 0))
+        (Pure 'Nothing)
+        (Pure ('Just (T.Head1 sym (TL.CmpSymbol sym "\128"))))
+    )
+
+-- | Get the tail of a type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Tail ('Text "haamu"))
+-- Eval (Tail ('Text "haamu")) :: Maybe Text
+-- = 'Just ('Text "aamu")
+--
+-- >>> :kind! Eval (Tail ('Text ""))
+-- Eval (Tail ('Text "")) :: Maybe Text
+-- = 'Nothing
+data Tail :: Text -> Exp (Maybe Text)
+type instance Eval (Tail ('Text sym)) = Eval (F.FMap Singleton =<< T.Uncons sym)
+
+-- | Take all except the last symbol from type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Init ('Text "aamun"))
+-- Eval (Init ('Text "aamun")) :: Maybe Text
+-- = 'Just ('Text "aamu")
+--
+-- >>> :kind! Eval (Init ('Text ""))
+-- Eval (Init ('Text "")) :: Maybe Text
+-- = 'Nothing
+data Init :: Text -> Exp (Maybe Text)
+type instance Eval (Init txt) = Eval (F.FMap FromList =<< F.Init =<< ToList txt)
+
+
+-- | Compare the length of type-level text to given Nat and give
+-- the Ordering.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (CompareLength ('Text "aamu") 3)
+-- Eval (CompareLength ('Text "aamu") 3) :: Ordering
+-- = 'GT
+data CompareLength :: Text -> Nat -> Exp Ordering
+type instance Eval (CompareLength txt n) = TL.CmpNat (Length @@ txt) n
+
+
+
+-- | FMap for type-level text.
+--
+-- === __Example__
+--
+-- >>> :{
+-- data IsIsymb :: Symbol -> Exp Bool
+-- type instance Eval (IsIsymb s) = Eval ("i" S.== s)
+-- data Isymb2e :: Symbol -> Exp Symbol
+-- type instance Eval (Isymb2e s) = Eval
+--     (If (IsIsymb @@ s)
+--         (Pure "e")
+--         (Pure s)
+--     )
+-- :}
+--
+-- >>> :kind! Eval (FMap Isymb2e ('Text "imu"))
+-- Eval (FMap Isymb2e ('Text "imu")) :: Text
+-- = 'Text "emu"
+data FMap :: (Symbol -> Exp Symbol) -> Text -> Exp Text
+type instance Eval (FMap f txt) = Eval (FromSymbolList =<< F.FMap f =<< ToSymbolList txt)
+
+data FMapT :: (Text -> Exp Text) -> Text -> Exp Text
+type instance Eval (FMapT f txt) = Eval (FromList =<< F.FMap f =<< ToList txt)
+
+
+-- | Intercalate for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Intercalate ('Text " & ") ('[ 'Text "aamu", 'Text "valo"]))
+-- Eval (Intercalate ('Text " & ") ('[ 'Text "aamu", 'Text "valo"])) :: Text
+-- = 'Text "aamu & valo"
+data Intercalate :: Text -> [Text] -> Exp Text
+type instance Eval (Intercalate txt txts) = 
+    Eval (FromList =<< F.Intercalate '[txt] =<< F.FMap ToList txts)
+
+
+-- | Intersperse for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Intersperse "." ('Text "aamu"))
+-- Eval (Intersperse "." ('Text "aamu")) :: Text
+-- = 'Text "a.a.m.u"
+data Intersperse :: Symbol -> Text -> Exp Text
+type instance Eval (Intersperse s ('Text txt)) =
+    Eval (FromSymbolList =<< F.Intersperse s (T.ToList txt))
+
+-- | Reverse for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Reverse ('Text "aamu"))
+-- Eval (Reverse ('Text "aamu")) :: Text
+-- = 'Text "umaa"
+--
+-- >>> :kind! Eval (Reverse =<< Reverse ('Text "aamu"))
+-- Eval (Reverse =<< Reverse ('Text "aamu")) :: Text
+-- = 'Text "aamu"
+data Reverse :: Text -> Exp Text
+type instance Eval (Reverse txt) =  Eval (FromList =<< F.Reverse =<< ToList txt)
+
+-- | Replace for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Replace ('Text "tu") ('Text "la") ('Text "tuututtaa"))
+-- Eval (Replace ('Text "tu") ('Text "la") ('Text "tuututtaa")) :: Text
+-- = 'Text "laulattaa"
+data Replace :: Text -> Text -> Text -> Exp Text
+type instance Eval (Replace orig new txt) =
+    Eval (Intercalate new =<< SplitOn orig txt)
+
+
+-- | Concat for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Concat '[ 'Text "la", 'Text "kana"])
+-- Eval (Concat '[ 'Text "la", 'Text "kana"]) :: Text
+-- = 'Text "lakana"
+data Concat :: [Text] -> Exp Text
+type instance Eval (Concat lst) = 
+    'Text (T.ToSymbol2 @@ Eval (F.FMap ToSymbol lst))
+
+
+
+-- | FConcatMap for type-level text.
+--
+-- === __Example__
+--
+-- >>> :{
+-- data IsIsymb :: Symbol -> Exp Bool
+-- type instance Eval (IsIsymb s) = Eval ("i" S.== s)
+-- data Isymb2aa :: Symbol -> Exp Text
+-- type instance Eval (Isymb2aa s) = Eval
+--     (If (IsIsymb @@ s)
+--         (Pure ('Text "aa"))
+--         (Pure ('Text s))
+--     )
+-- :}
+--
+-- >>> :kind! Eval (FConcatMap Isymb2aa ('Text "imu ih"))
+-- Eval (FConcatMap Isymb2aa ('Text "imu ih")) :: Text
+-- = 'Text "aamu aah"
+data FConcatMap :: (Symbol -> Exp Text) -> Text -> Exp Text
+type instance Eval (FConcatMap f ('Text lst)) = Eval (Concat =<< F.FMap f (T.ToList lst))
+
+-- | Any for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Any S.IsDigit ('Text "aamu1"))
+-- Eval (Any S.IsDigit ('Text "aamu1")) :: Bool
+-- = 'True
+--
+-- >>> :kind! Eval (Any S.IsDigit ('Text "aamu"))
+-- Eval (Any S.IsDigit ('Text "aamu")) :: Bool
+-- = 'False
+data Any :: (Symbol -> Exp Bool) -> Text -> Exp Bool
+type instance Eval (Any f ('Text sym)) = Eval (F.Any f (T.ToList sym))
+
+
+-- | All for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (All S.IsDigit ('Text "aamu1"))
+-- Eval (All S.IsDigit ('Text "aamu1")) :: Bool
+-- = 'False
+--
+-- >>> :kind! Eval (All S.IsDigit ('Text "321"))
+-- Eval (All S.IsDigit ('Text "321")) :: Bool
+-- = 'True
+data All :: (Symbol -> Exp Bool) -> Text -> Exp Bool
+type instance Eval (All f ('Text lst)) = Eval (F.All f (T.ToList lst))
+
+
+
+
+
+-- | Take for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Take 4 ('Text "aamun"))
+-- Eval (Take 4 ('Text "aamun")) :: Text
+-- = 'Text "aamu"
+data Take :: Nat -> Text -> Exp Text
+type instance Eval (Take n ('Text lst)) = Eval (FromSymbolList =<< F.Take n (T.ToList lst))
+
+
+-- | TakeEnd for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (TakeEnd 4 ('Text "haamu"))
+-- Eval (TakeEnd 4 ('Text "haamu")) :: Text
+-- = 'Text "aamu"
+data TakeEnd :: Nat -> Text -> Exp Text
+type instance Eval (TakeEnd n ('Text lst)) =
+    Eval (FromSymbolList =<< F.Reverse =<< F.Take n =<< F.Reverse (T.ToList lst))
+
+
+-- | Drop for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Drop 2 ('Text "aamuna"))
+-- Eval (Drop 2 ('Text "aamuna")) :: Text
+-- = 'Text "muna"
+data Drop :: Nat -> Text -> Exp Text
+type instance Eval (Drop n ('Text lst)) = Eval (FromSymbolList =<< F.Drop n (T.ToList lst))
+
+-- | DropEnd for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (DropEnd 2 ('Text "aamuna"))
+-- Eval (DropEnd 2 ('Text "aamuna")) :: Text
+-- = 'Text "aamu"
+data DropEnd :: Nat -> Text -> Exp Text
+type instance Eval (DropEnd n ('Text lst)) =
+    Eval (FromSymbolList =<< F.Reverse =<< F.Drop n =<< F.Reverse (T.ToList lst))
+
+
+-- | TakeWhile for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (TakeWhile (Not <=< S.IsDigit) ('Text "aamu12"))
+-- Eval (TakeWhile (Not <=< S.IsDigit) ('Text "aamu12")) :: Text
+-- = 'Text "aamu"
+data TakeWhile :: (Symbol -> Exp Bool) -> Text -> Exp Text
+type instance Eval (TakeWhile f ('Text lst)) = Eval (FromSymbolList =<< F.TakeWhile f (T.ToList lst))
+
+
+-- | TakeWhileEnd for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (TakeWhileEnd (Not <=< S.IsDigit) ('Text "12aamu"))
+-- Eval (TakeWhileEnd (Not <=< S.IsDigit) ('Text "12aamu")) :: Text
+-- = 'Text "aamu"
+data TakeWhileEnd :: (Symbol -> Exp Bool) -> Text -> Exp Text
+type instance Eval (TakeWhileEnd f ('Text lst)) =
+    Eval (FromSymbolList =<< F.Reverse =<< F.TakeWhile f =<< F.Reverse (T.ToList lst))
+
+
+-- | DropWhile for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (DropWhile S.IsDigit ('Text "12aamu"))
+-- Eval (DropWhile S.IsDigit ('Text "12aamu")) :: Text
+-- = 'Text "aamu"
+data DropWhile :: (Symbol -> Exp Bool) -> Text -> Exp Text
+type instance Eval (DropWhile f ('Text lst)) = Eval (FromSymbolList =<< F.DropWhile f (T.ToList lst))
+
+
+-- | DropWhileEnd for type-level text.
+-- === __Example__
+--
+-- >>> :kind! Eval (DropWhileEnd S.IsDigit ('Text "aamu12"))
+-- Eval (DropWhileEnd S.IsDigit ('Text "aamu12")) :: Text
+-- = 'Text "aamu"
+data DropWhileEnd :: (Symbol -> Exp Bool) -> Text -> Exp Text
+type instance Eval (DropWhileEnd f ('Text lst)) =
+    Eval (FromSymbolList =<< F.Reverse =<< F.DropWhile f =<< F.Reverse (T.ToList lst))
+
+
+-- | DropAround for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (DropAround S.IsDigit ('Text "34aamu12"))
+-- Eval (DropAround S.IsDigit ('Text "34aamu12")) :: Text
+-- = 'Text "aamu"
+data DropAround :: (Symbol -> Exp Bool) -> Text -> Exp Text
+type instance Eval (DropAround f txt) = Eval (DropWhile f =<< DropWhileEnd f txt)
+
+
+
+-- | Strip the space, newline and tab -symbols from the beginning and and
+-- of type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Strip ('Text "  aamu \n"))
+-- Eval (Strip ('Text "  aamu \n")) :: Text
+-- = 'Text "aamu"
+data Strip :: Text -> Exp Text
+type instance Eval (Strip txt) = Eval (DropAround S.IsSpaceDelim txt)
+
+
+-- | SplitOn for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (SplitOn ('Text "ab") ('Text "cdabfgabh"))
+-- Eval (SplitOn ('Text "ab") ('Text "cdabfgabh")) :: [Text]
+-- = '[ 'Text "cd", 'Text "fg", 'Text "h"]
+data SplitOn :: Text -> Text -> Exp [Text]
+type instance Eval (SplitOn ('Text sep) ('Text txt)) =
+    Eval (F.FMap FromSymbolList =<< SOLoop (T.ToList sep) '( '[], T.ToList txt))
+
+
+-- | Helper for SplitOn
+--
+-- >>> :kind! Eval (SOTake '["a", "b"] '[ "c", "d", "a", "b", "f", "g"] '[])
+-- Eval (SOTake '["a", "b"] '[ "c", "d", "a", "b", "f", "g"] '[]) :: ([Symbol],
+--                                                                    [Symbol])
+-- = '( '["c", "d"], '["f", "g"])
+data SOTake :: [Symbol] -> [Symbol] -> [Symbol] -> Exp ([Symbol], [Symbol])
+type instance Eval (SOTake sep '[] accum) = '(accum, '[])
+type instance Eval (SOTake sep (t ': txt) accum) = Eval
+    (If (Eval (F.IsPrefixOf sep (t ': txt)))
+        (Pure '(accum, Eval (F.Drop (Eval (F.Length sep)) (t ': txt))))
+        (SOTake sep txt (Eval (accum ++ '[t])))
+    )
+
+-- | Helper for SplitOn
+data SOLoop :: [Symbol] -> ([[Symbol]],[Symbol]) -> Exp [[Symbol]]
+type instance Eval (SOLoop sep '(acc, '[])) = acc
+type instance Eval (SOLoop sep '(acc, t ': txt)) =
+    Eval (SOLoop sep =<< First (F.Snoc acc) =<< SOTake sep (t ': txt) '[])
+
+
+
+-- | Split for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Split S.IsSpace (Eval (Singleton "cd bf abh")))
+-- Eval (Split S.IsSpace (Eval (Singleton "cd bf abh"))) :: [Text]
+-- = '[ 'Text "cd", 'Text "bf", 'Text "abh"]
+data Split :: (Symbol -> Exp Bool) -> Text -> Exp [Text]
+type instance Eval (Split p ('Text txt)) =
+    Eval (F.FMap FromSymbolList =<< SplitLoop p '( '[], T.ToList txt))
+
+-- | Helper for Split
+data SplitTake :: (Symbol -> Exp Bool) -> [Symbol] -> [Symbol] -> Exp ([Symbol], [Symbol])
+type instance Eval (SplitTake p '[] accum) = '(accum, '[])
+type instance Eval (SplitTake p (t ': txt) accum) = Eval
+    (If (Eval (p t))
+        (Pure '(accum, txt))
+        (SplitTake p txt (Eval (accum ++ '[t])))
+    )
+
+-- | Helper for Split
+data SplitLoop :: (Symbol -> Exp Bool) -> ([[Symbol]],[Symbol]) -> Exp [[Symbol]]
+type instance Eval (SplitLoop p '(acc, '[])) = acc
+type instance Eval (SplitLoop p '(acc, t ': txt)) = 
+    Eval (SplitLoop p =<< First (F.Snoc acc) =<< SplitTake p (t ': txt) '[])
+
+
+
+-- | Lines for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Lines =<< Singleton "ok\nhmm\nab")
+-- Eval (Lines =<< Singleton "ok\nhmm\nab") :: [Text]
+-- = '[ 'Text "ok", 'Text "hmm", 'Text "ab"]
+data Lines :: Text -> Exp [Text]
+type instance Eval (Lines txt) = Eval (Split S.IsNewLine txt)
+
+-- | Words for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Words =<< Singleton "ok hmm\nab")
+-- Eval (Words =<< Singleton "ok hmm\nab") :: [Text]
+-- = '[ 'Text "ok", 'Text "hmm", 'Text "ab"]
+data Words :: Text -> Exp [Text]
+type instance Eval (Words txt) = Eval (Split S.IsSpaceDelim txt)
+
+-- | Unlines for type-level text. This adds a newline to each Text and then
+-- concats them.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Unlines '[ 'Text "ok", 'Text "hmm", 'Text "ab"])
+-- Eval (Unlines '[ 'Text "ok", 'Text "hmm", 'Text "ab"]) :: Text
+-- = 'Text "ok\nhmm\nab\n"
+data Unlines :: [Text] -> Exp Text
+type instance Eval (Unlines txts) = 
+    Eval (Concat =<< F.FMap (Flip Append (Singleton @@ "\n")) txts)
+
+-- | Unwords for type-level text. This uses 'Intercalate' to add space-symbol
+-- between the given texts.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Unwords '[ 'Text "ok", 'Text "hmm", 'Text "ab"])
+-- Eval (Unwords '[ 'Text "ok", 'Text "hmm", 'Text "ab"]) :: Text
+-- = 'Text "ok hmm ab"
+data Unwords :: [Text] -> Exp Text
+type instance Eval (Unwords txts) = Eval (Intercalate ('Text " ") txts)
+
+
+-- | IsPrefixOf for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (IsPrefixOf ('Text "aa") ('Text "aamiainen"))
+-- Eval (IsPrefixOf ('Text "aa") ('Text "aamiainen")) :: Bool
+-- = 'True
+data IsPrefixOf :: Text -> Text -> Exp Bool
+type instance Eval (IsPrefixOf ('Text l1) ('Text l2) ) =
+    Eval (F.IsPrefixOf (T.ToList l1) (T.ToList l2))
+
+
+-- | IsSuffixOf for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (IsSuffixOf ('Text "nen") ('Text "aamiainen"))
+-- Eval (IsSuffixOf ('Text "nen") ('Text "aamiainen")) :: Bool
+-- = 'True
+data IsSuffixOf :: Text -> Text -> Exp Bool
+type instance Eval (IsSuffixOf ('Text l1) ('Text l2) ) =
+    Eval (F.IsSuffixOf (T.ToList l1) (T.ToList l2))
+
+
+-- | IsInfixOf for type-level text.
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (IsInfixOf ('Text "mia") ('Text "aamiainen"))
+-- Eval (IsInfixOf ('Text "mia") ('Text "aamiainen")) :: Bool
+-- = 'True
+data IsInfixOf :: Text -> Text -> Exp Bool
+type instance Eval (IsInfixOf ('Text l1) ('Text l2) ) =
+    Eval (F.IsInfixOf (T.ToList l1) (T.ToList l2))
diff --git a/src/Fcf/Data/Reflect.hs b/src/Fcf/Data/Reflect.hs
new file mode 100644
--- /dev/null
+++ b/src/Fcf/Data/Reflect.hs
@@ -0,0 +1,228 @@
+{-# LANGUAGE CPP                    #-}
+{-# LANGUAGE FlexibleContexts       #-}
+{-# LANGUAGE FlexibleInstances      #-}
+{-# LANGUAGE MultiParamTypeClasses  #-}
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{-|
+Module      : Fcf.Data.Reflect
+Description : List helpers / utils
+Copyright   : (c) gspia 2023-
+License     : BSD
+Maintainer  : gspia
+
+= Fcf.Data.Reflect
+
+Helpers to get results from type-level computations into the fromType-level.
+
+-}
+
+--------------------------------------------------------------------------------
+
+module Fcf.Data.Reflect where
+
+import qualified GHC.TypeLits as TL
+import           GHC.TypeLits (Nat, Symbol, KnownNat, KnownSymbol)
+import           Data.String (fromString, IsString)
+import           Data.Proxy
+import           Data.Typeable (Typeable, typeRep)
+import           Data.Kind (Type)
+import qualified Data.Map as DM
+import qualified Data.IntMap.Strict as IMS
+import qualified Data.Set as S
+-- #if __GLASGOW_HASKELL__ >= 902
+-- #endif
+import qualified Data.Tree as T
+
+import qualified Fcf.Data.MapC as MC
+import qualified Fcf.Data.NatMap as NM
+import qualified Fcf.Data.Set as FS
+#if __GLASGOW_HASKELL__ >= 902
+import qualified Fcf.Data.NewText as FTxt
+#endif
+import qualified Fcf.Data.Tree as FT
+
+--------------------------------------------------------------------------------
+
+-- | Reflect a list of Nats
+--
+-- Note that you may also use the KnownVal methods given below.
+--
+-- This method is taken from
+-- https://hackage.haskell.org/package/numhask-array-0.10.1/docs/src/NumHask.Array.Shape.html#natVals
+--
+-- === __Example__
+--
+-- > :{
+-- afun :: forall n. (n ~ '[1,2,3,4]) => [Int]
+-- afun = natVals @n Proxy
+-- :}
+--
+-- > afun
+-- [1,2,3,4]
+class KnownNats (ns :: [Nat]) where
+  natVals :: Proxy ns -> [Int]
+
+{-# DEPRECATED KnownNats "Replaced with KnownVal" #-}
+
+instance KnownNats '[] where
+  natVals _ = []
+
+instance (TL.KnownNat n, KnownNats ns) => KnownNats (n : ns) where
+  natVals _ = fromInteger (TL.natVal (Proxy @n)) : natVals (Proxy @ns)
+
+
+--------------------------------------------------------------------------------
+
+class KnownVal val kind where
+    fromType :: Proxy kind -> val
+
+instance (KnownNat n, Num a) => KnownVal a (n :: Nat) where
+    fromType _ = fromInteger $ TL.natVal (Proxy @n)
+
+instance KnownVal Bool 'True where fromType _ = True
+instance KnownVal Bool 'False where fromType _ = False
+instance KnownVal () '() where fromType _ = ()
+
+instance (IsString str, KnownSymbol s) => KnownVal str (s :: Symbol) where
+    fromType _ = fromString $ TL.symbolVal (Proxy @s)
+
+#if __GLASGOW_HASKELL__ >= 920
+instance (TL.KnownChar c) => KnownVal Char c where
+    fromType _ = TL.charVal (Proxy @c)
+#endif
+
+instance (IsString str, Typeable typ) => KnownVal str (typ :: Type) where
+    fromType = fromString . show . typeRep
+
+#if __GLASGOW_HASKELL__ >= 902
+
+-- | Text instance.
+--
+-- === __Example__
+--
+-- > import qualified Data.Text as Txt
+-- > :{
+-- afun :: forall r. (r ~ 'FTxt.Text "hmm") => Txt.Text
+-- afun = fromType (Proxy @r)
+-- :}
+--
+-- > afun
+-- "hmm"
+instance (IsString str, KnownSymbol sym) => KnownVal str ('FTxt.Text sym)
+  where
+    fromType _ = fromType @str (Proxy @sym) 
+
+#endif
+
+--------------------------------------------------------------------------------
+
+-- List instances
+
+instance KnownVal [a] '[] where
+    fromType _ = []
+
+instance (KnownVal val x, KnownVal [val] xs) => KnownVal [val] (x ': xs) where
+    fromType _ = fromType (Proxy @x) : fromType (Proxy @xs)
+
+--------------------------------------------------------------------------------
+
+-- Trees
+--
+instance (KnownVal val k, KnownVal (T.Forest val) trees) => KnownVal (T.Tree val) ('FT.Node k trees)
+  where
+    fromType _ = T.Node (fromType (Proxy @k)) (fromType (Proxy @trees))
+
+--------------------------------------------------------------------------------
+
+-- NatMaps / IntMaps
+--
+instance (KnownVal [(Int,val)] pairs) => KnownVal (IMS.IntMap val) ('NM.NatMap pairs)
+  where
+    fromType _ = IMS.fromList (fromType (Proxy @pairs))
+
+instance (KnownVal [(Int,val)] pairs) => KnownVal (IMS.IntMap val) (pairs :: [(Nat, val')])
+  where
+    fromType _ = IMS.fromList (fromType (Proxy @pairs))
+
+--------------------------------------------------------------------------------
+
+-- Maps
+
+instance (Ord key, KnownVal [(key,val)] pairs) => KnownVal (DM.Map key val) ('MC.MapC pairs)
+  where
+    fromType _ = DM.fromList (fromType (Proxy @pairs))
+
+instance (Ord key, KnownVal [(key,val)] pairs) => KnownVal (DM.Map key val) (pairs :: [(key',val')])
+  where
+    fromType _ = DM.fromList (fromType (Proxy @pairs))
+
+--------------------------------------------------------------------------------
+
+-- Set
+
+instance (Ord val, KnownVal [val] kind) => KnownVal (S.Set val) ('FS.Set kind)
+  where
+    fromType _ = S.fromList (fromType (Proxy @kind))
+
+instance (Ord val, KnownVal [val] kind) => KnownVal (S.Set val) (kind :: [kind'])
+  where
+    fromType _ = S.fromList (fromType (Proxy @kind))
+ 
+--------------------------------------------------------------------------------
+
+-- Either
+
+instance (KnownVal a1 a) => KnownVal (Either a1 b1) ('Left a) where
+    fromType _ = Left (fromType @a1 (Proxy @a))
+
+instance (KnownVal b1 b) => KnownVal (Either a1 b1) ('Right b) where
+    fromType _ = Right (fromType @b1 (Proxy @b))
+
+--------------------------------------------------------------------------------
+
+-- Maybe
+
+instance (KnownVal a1 a) => KnownVal (Maybe a1) ('Just a) where
+    fromType _ = Just (fromType @a1 (Proxy @a))
+
+instance KnownVal (Maybe a1) 'Nothing where
+    fromType _ = Nothing
+
+--------------------------------------------------------------------------------
+
+-- Tuples
+
+instance (KnownVal a1 a, KnownVal b1 b) => KnownVal (a1,b1) '(a,b) where
+    fromType _ = (fromType @a1 (Proxy @a), fromType @b1 (Proxy @b))
+
+instance (KnownVal a1 a, KnownVal b1 b, KnownVal c1 c) => KnownVal (a1,b1,c1) '(a,b,c) where
+    fromType _ = (fromType @a1 (Proxy @a), fromType @b1 (Proxy @b), fromType @c1 (Proxy @c))
+
+instance (KnownVal a1 a, KnownVal b1 b, KnownVal c1 c, KnownVal d1 d) => KnownVal (a1,b1,c1,d1) '(a,b,c,d) where
+    fromType _ = (fromType @a1 (Proxy @a), fromType @b1 (Proxy @b), fromType @c1 (Proxy @c), fromType @d1 (Proxy @d))
+
+instance (KnownVal a1 a, KnownVal b1 b, KnownVal c1 c, KnownVal d1 d, KnownVal e1 e) => KnownVal (a1,b1,c1,d1,e1) '(a,b,c,d,e) where
+    fromType _ = (fromType @a1 (Proxy @a), fromType @b1 (Proxy @b), fromType @c1 (Proxy @c), fromType @d1 (Proxy @d), fromType @e1 (Proxy @e))
+
+--------------------------------------------------------------------------------
+
+-- ErrorMessage from GHC.TypeLits
+
+instance (IsString str, KnownSymbol sym) => KnownVal str ('TL.Text sym) where
+  fromType _ = fromType @str (Proxy @sym)
+
+instance (IsString str, Typeable typ) => KnownVal str ('TL.ShowType typ) where
+  fromType _ = fromString $ show $ typeRep (Proxy @typ)
+
+instance (IsString str, KnownVal str err1, KnownVal str err2, Semigroup str) => KnownVal str (err1 'TL.:<>: err2) where
+  fromType _ = fromType (Proxy @err1) <> fromType (Proxy @err2)
+
+instance (IsString str, KnownVal str err1, KnownVal str err2, Semigroup str) => KnownVal str (err1 'TL.:$$: err2) where
+  fromType _ = fromType (Proxy @err1) <> fromString "\n" <> fromType (Proxy @err2)
diff --git a/src/Fcf/Data/Set.hs b/src/Fcf/Data/Set.hs
--- a/src/Fcf/Data/Set.hs
+++ b/src/Fcf/Data/Set.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE DataKinds              #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
 {-# LANGUAGE TypeOperators          #-}
@@ -63,7 +61,7 @@
 
 import           Fcf ( Eval, Exp, type (=<<), type (<=<), type (&&)
                      , Not, If, Map, Flip, TyEq )
-import qualified Fcf as Fcf (Foldr, Filter)
+import qualified Fcf (Foldr, Filter)
 import           Fcf.Class.Foldable (All, Any)
 import           Fcf.Data.List ( Elem, Cons, Concat, Reverse, Length, type (++)
                                , ZipWith, Replicate)
@@ -75,28 +73,18 @@
 
 --------------------------------------------------------------------------------
 
--- For the doctests:
-
--- $setup
--- >>> import qualified GHC.TypeLits as TL
--- >>> import           Fcf.Data.Nat
--- >>> import           Fcf.Data.Symbol
--- >>> import           Fcf.Alg.Sort
-
---------------------------------------------------------------------------------
-
 -- | Set-definition.
-data Set a = Set [a]
+newtype Set a = Set [a]
 
 
 --------------------------------------------------------------------------------
 
 -- | Empty
--- 
+--
 -- === __Example__
--- 
--- >>> :kind! (Eval Empty :: Set Nat)
--- (Eval Empty :: Set Nat) :: Set Nat
+--
+-- > :kind! (Eval Empty :: Set Nat)
+-- (Eval Empty :: Set Nat) :: Set TL.Natural
 -- = 'Set '[]
 --
 -- See also the other examples in this module.
@@ -104,11 +92,11 @@
 type instance Eval Empty = 'Set '[]
 
 -- | Singleton
--- 
+--
 -- === __Example__
--- 
--- >>> :kind! Eval (Singleton 1)
--- Eval (Singleton 1) :: Set Nat
+--
+-- > :kind! Eval (Singleton 1)
+-- Eval (Singleton 1) :: Set TL.Natural
 -- = 'Set '[1]
 data Singleton :: v -> Exp (Set v)
 type instance Eval (Singleton v) = 'Set '[v]
@@ -118,12 +106,12 @@
 --
 -- === __Example__
 --
--- >>> :kind! Eval (Insert 3 =<< FromList '[1, 2])
--- Eval (Insert 3 =<< FromList '[1, 2]) :: Set Nat
+-- > :kind! Eval (Insert 3 =<< FromList '[1, 2])
+-- Eval (Insert 3 =<< FromList '[1, 2]) :: Set TL.Natural
 -- = 'Set '[3, 1, 2]
 --
--- >>> :kind! Eval (Insert 2 =<< FromList '[1, 2])
--- Eval (Insert 2 =<< FromList '[1, 2]) :: Set Nat
+-- > :kind! Eval (Insert 2 =<< FromList '[1, 2])
+-- Eval (Insert 2 =<< FromList '[1, 2]) :: Set TL.Natural
 -- = 'Set '[1, 2]
 data Insert :: v -> Set v -> Exp (Set v)
 type instance Eval (Insert v ('Set lst)) =
@@ -132,15 +120,15 @@
         ('Set (v ': lst))
 
 -- | Delete
--- 
+--
 -- === __Example__
--- 
--- >>> :kind! Eval (Delete 5 =<< FromList '[5, 3])
--- Eval (Delete 5 =<< FromList '[5, 3]) :: Set Nat
+--
+-- > :kind! Eval (Delete 5 =<< FromList '[5, 3])
+-- Eval (Delete 5 =<< FromList '[5, 3]) :: Set TL.Natural
 -- = 'Set '[3]
 --
--- >>> :kind! Eval (Delete 7 =<< FromList '[5, 3])
--- Eval (Delete 7 =<< FromList '[5, 3]) :: Set Nat
+-- > :kind! Eval (Delete 7 =<< FromList '[5, 3])
+-- Eval (Delete 7 =<< FromList '[5, 3]) :: Set TL.Natural
 -- = 'Set '[5, 3]
 data Delete :: v -> Set v -> Exp (Set v)
 type instance Eval (Delete v ('Set lst)) =
@@ -149,11 +137,12 @@
 -- | Member
 --
 -- === __Example__
--- 
--- >>> :kind! Eval (Member 5 =<< FromList '[5, 3])
+--
+-- > :kind! Eval (Member 5 =<< FromList '[5, 3])
 -- Eval (Member 5 =<< FromList '[5, 3]) :: Bool
 -- = 'True
--- >>> :kind! Eval (Member 7 =<< FromList '[5, 3])
+--
+-- > :kind! Eval (Member 7 =<< FromList '[5, 3])
 -- Eval (Member 7 =<< FromList '[5, 3]) :: Bool
 -- = 'False
 data Member :: v -> Set v -> Exp Bool
@@ -162,11 +151,12 @@
 -- | NotMember
 --
 -- === __Example__
--- 
--- >>> :kind! Eval (NotMember 5 =<< FromList '[5, 3])
+--
+-- > :kind! Eval (NotMember 5 =<< FromList '[5, 3])
 -- Eval (NotMember 5 =<< FromList '[5, 3]) :: Bool
 -- = 'False
--- >>> :kind! Eval (NotMember 7 =<< FromList '[5, 3])
+--
+-- > :kind! Eval (NotMember 7 =<< FromList '[5, 3])
 -- Eval (NotMember 7 =<< FromList '[5, 3]) :: Bool
 -- = 'True
 data NotMember :: v -> Set v -> Exp Bool
@@ -177,11 +167,12 @@
 -- | Null
 --
 -- === __Example__
--- 
--- >>> :kind! Eval (Null =<< FromList '[5, 3])
+--
+-- > :kind! Eval (Null =<< FromList '[5, 3])
 -- Eval (Null =<< FromList '[5, 3]) :: Bool
 -- = 'False
--- >>> :kind! Eval (Null =<< Empty)
+-- 
+-- > :kind! Eval (Null =<< Empty)
 -- Eval (Null =<< Empty) :: Bool
 -- = 'True
 data Null :: Set v -> Exp Bool
@@ -192,31 +183,31 @@
 -- | Size
 --
 -- === __Example__
--- 
--- >>> :kind! Eval (Size =<< FromList '[5, 3])
--- Eval (Size =<< FromList '[5, 3]) :: Nat
+--
+-- > :kind! Eval (Size =<< FromList '[5, 3])
+-- Eval (Size =<< FromList '[5, 3]) :: TL.Natural
 -- = 2
 data Size :: Set v -> Exp TL.Nat
 type instance Eval (Size ('Set lst)) = Eval (Length lst)
 
 
--- | IsSubsetOf 
+-- | IsSubsetOf
 --
 -- === __Example__
--- 
--- >>> :kind! Eval (IsSubsetOf ('Set '[]) ('Set '[0,1,2,3,4]))
+--
+-- > :kind! Eval (IsSubsetOf ('Set '[]) ('Set '[0,1,2,3,4]))
 -- Eval (IsSubsetOf ('Set '[]) ('Set '[0,1,2,3,4])) :: Bool
 -- = 'True
 --
--- >>> :kind! Eval (IsSubsetOf ('Set '[0,1]) ('Set '[0,1,2,3,4]))
+-- > :kind! Eval (IsSubsetOf ('Set '[0,1]) ('Set '[0,1,2,3,4]))
 -- Eval (IsSubsetOf ('Set '[0,1]) ('Set '[0,1,2,3,4])) :: Bool
 -- = 'True
 --
--- >>> :kind! Eval (IsSubsetOf ('Set '[0,2,1,3,4]) ('Set '[0,1,2,3,4]))
+-- > :kind! Eval (IsSubsetOf ('Set '[0,2,1,3,4]) ('Set '[0,1,2,3,4]))
 -- Eval (IsSubsetOf ('Set '[0,2,1,3,4]) ('Set '[0,1,2,3,4])) :: Bool
 -- = 'True
 --
--- >>> :kind! Eval (IsSubsetOf ('Set '[0,1,2,3,4,5]) ('Set '[0,1,2,3,4]))
+-- > :kind! Eval (IsSubsetOf ('Set '[0,1,2,3,4,5]) ('Set '[0,1,2,3,4]))
 -- Eval (IsSubsetOf ('Set '[0,1,2,3,4,5]) ('Set '[0,1,2,3,4])) :: Bool
 -- = 'False
 data IsSubsetOf :: Set a -> Set a -> Exp Bool
@@ -224,15 +215,15 @@
     Eval (All (Flip Elem s2) s1)
 
 
--- | IsProperSubsetOf 
+-- | IsProperSubsetOf
 --
 -- === __Example__
--- 
--- >>> :kind! Eval (IsProperSubsetOf ('Set '[0,1,2,3,4]) ('Set '[0,1,2,3,4]))
+--
+-- > :kind! Eval (IsProperSubsetOf ('Set '[0,1,2,3,4]) ('Set '[0,1,2,3,4]))
 -- Eval (IsProperSubsetOf ('Set '[0,1,2,3,4]) ('Set '[0,1,2,3,4])) :: Bool
 -- = 'False
 --
--- >>> :kind! Eval (IsProperSubsetOf ('Set '[0,2,1,3]) ('Set '[0,1,2,3,4]))
+-- > :kind! Eval (IsProperSubsetOf ('Set '[0,2,1,3]) ('Set '[0,1,2,3,4]))
 -- Eval (IsProperSubsetOf ('Set '[0,2,1,3]) ('Set '[0,1,2,3,4])) :: Bool
 -- = 'True
 data IsProperSubsetOf :: Set a -> Set a -> Exp Bool
@@ -245,10 +236,10 @@
 -- | Type-level set union.
 --
 -- === __Example__
--- 
--- >>> :kind! Eval (Union (Eval (FromList '[5, 3])) (Eval (FromList '[5, 7])) )
--- Eval (Union (Eval (FromList '[5, 3])) (Eval (FromList '[5, 7])) ) :: Set 
---                                                                        Nat
+--
+-- > :kind! Eval (Union (Eval (FromList '[5, 3])) (Eval (FromList '[5, 7])) )
+-- Eval (Union (Eval (FromList '[5, 3])) (Eval (FromList '[5, 7])) ) :: Set
+--                                                                        TL.Natural
 -- = 'Set '[7, 5, 3]
 data Union :: Set v -> Set v -> Exp (Set v)
 type instance Eval (Union ('Set lst1) ('Set lst2)) =
@@ -262,12 +253,12 @@
 
 
 -- | Type-level set difference.
--- 
+--
 -- === __Example__
--- 
--- >>> :kind! Eval (Difference (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7])))
--- Eval (Difference (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7]))) :: Set 
---                                                                            Nat
+--
+-- > :kind! Eval (Difference (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7])))
+-- Eval (Difference (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7]))) :: Set
+--                                                                            TL.Natural
 -- = 'Set '[3]
 data Difference :: Set v -> Set v -> Exp (Set v)
 type instance Eval (Difference ('Set lst1) ('Set lst2)) =
@@ -281,10 +272,10 @@
 -- | Type-level set intersection.
 --
 -- === __Example__
--- 
--- >>> :kind! Eval (Intersection (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7])))
--- Eval (Intersection (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7]))) :: Set 
---                                                                              Nat
+--
+-- > :kind! Eval (Intersection (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7])))
+-- Eval (Intersection (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7]))) :: Set
+--                                                                              TL.Natural
 -- = 'Set '[5]
 data Intersection :: Set v -> Set v -> Exp (Set v)
 type instance Eval (Intersection ('Set lst1) ('Set lst2)) =
@@ -307,10 +298,10 @@
 -- helper for PowerSet
 data ExtendBitList :: [[Bool]] -> Exp [[Bool]]
 type instance Eval (ExtendBitList lst) =
-    Eval ((Eval (AddFalses lst)) ++ (Eval (AddTrues =<< Map Reverse lst)))
+    Eval (Eval (AddFalses lst) ++ Eval (AddTrues =<< Map Reverse lst))
 
 -- helper for PowerSet
--- :kind! Eval (Cata BuildGrayBitListsAlg=<< ListToFix =<< Replicate 3 '[])
+-- :kind! Eval (Cata BuildGrayBitListsAlg =<< ListToFix =<< Replicate 3 '[])
 data BuildGrayBitListsAlg :: Algebra (ListF [[Bool]]) [[Bool]]
 type instance Eval (BuildGrayBitListsAlg 'NilF) = '[ '[] ]
 type instance Eval (BuildGrayBitListsAlg ('ConsF _ lst)) = Eval (ExtendBitList lst)
@@ -330,20 +321,22 @@
 type instance Eval (SelectWithBools elms bls) =
     Eval (Concat =<< ZipWith SelWithBool elms bls)
 
--- | Calculate the power sets of a given type-level list. The algorithm is based 
+-- | Calculate the power sets of a given type-level list. The algorithm is based
 -- on Gray codes.
 --
 -- === __Example__
 --
--- >>> :kind! Eval (PowerSet =<< FromList '["a", "b", "c"])
--- Eval (PowerSet =<< FromList '["a", "b", "c"]) :: Set (Set Symbol)
+-- > :kind! Eval (PowerSet =<< FromList '["a", "b", "c"])
+-- Eval (PowerSet =<< FromList '["a", "b", "c"]) :: Set
+--                                                    (Set TL.Symbol)
 -- = 'Set
 --     '[ 'Set '[], 'Set '["c"], 'Set '["b"], 'Set '["b", "c"],
 --        'Set '["a"], 'Set '["a", "b"], 'Set '["a", "c"],
 --        'Set '["a", "b", "c"]]
 --
--- >>> :kind! Eval (PowerSet =<< FromList '[Int, Char, Maybe Int])
--- Eval (PowerSet =<< FromList '[Int, Char, Maybe Int]) :: Set (Set *)
+-- > :kind! Eval (PowerSet =<< FromList '[Int, Char, Maybe Int])
+-- Eval (PowerSet =<< FromList '[Int, Char, Maybe Int]) :: Set
+--                                                           (Set (*))
 -- = 'Set
 --     '[ 'Set '[], 'Set '[Maybe Int], 'Set '[Char],
 --        'Set '[Char, Maybe Int], 'Set '[Int], 'Set '[Int, Char],
@@ -360,9 +353,9 @@
 -- | Use FromList to construct a Set from type-level list.
 --
 -- === __Example__
--- 
--- >>> :kind! Eval (FromList '[1, 2])
--- Eval (FromList '[1, 2]) :: Set Nat
+--
+-- > :kind! Eval (FromList '[1, 2])
+-- Eval (FromList '[1, 2]) :: Set TL.Natural
 -- = 'Set '[1, 2]
 data FromList :: [v] -> Exp (Set v)
 type instance Eval (FromList lst) = 'Set lst
@@ -370,16 +363,15 @@
 -- | Get the type-level list out of the 'Set'.
 --
 -- === __Example__
--- 
--- >>> :kind! Eval (ToList =<< PowerSet =<< FromList '[1,2,3])
--- Eval (ToList =<< PowerSet =<< FromList '[1,2,3]) :: [Set Nat]
+--
+-- > :kind! Eval (ToList =<< PowerSet =<< FromList '[1,2,3])
+-- Eval (ToList =<< PowerSet =<< FromList '[1,2,3]) :: [Set
+--                                                        TL.Natural]
 -- = '[ 'Set '[], 'Set '[3], 'Set '[2], 'Set '[2, 3], 'Set '[1],
 --      'Set '[1, 2], 'Set '[1, 3], 'Set '[1, 2, 3]]
 --
--- >>> :kind! Eval (Qsort NatListOrd =<< Map ToList =<< ToList =<< PowerSet =<< FromList '[1,2,3])
--- Eval (Qsort NatListOrd =<< Map ToList =<< ToList =<< PowerSet =<< FromList '[1,2,3]) :: [[Nat]]
+-- > :kind! Eval (Qsort NatListOrd =<< Map ToList =<< ToList =<< PowerSet =<< FromList '[1,2,3])
+-- Eval (Qsort NatListOrd =<< Map ToList =<< ToList =<< PowerSet =<< FromList '[1,2,3]) :: [[TL.Natural]]
 -- = '[ '[], '[1], '[1, 2], '[1, 2, 3], '[1, 3], '[2], '[2, 3], '[3]]
 data ToList :: Set v -> Exp [v]
 type instance Eval (ToList ('Set lst)) = lst
-
-
diff --git a/src/Fcf/Data/Symbol.hs b/src/Fcf/Data/Symbol.hs
new file mode 100644
--- /dev/null
+++ b/src/Fcf/Data/Symbol.hs
@@ -0,0 +1,142 @@
+{-# LANGUAGE CPP                  #-}
+{-# LANGUAGE TypeFamilies         #-}
+{-# LANGUAGE TypeInType           #-}
+{-# LANGUAGE TypeOperators        #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{-|
+Module      : Fcf.Data.Symbol
+Description : Type-level Symbol helpers for Fcf libs
+Copyright   : (c) gspia 2023-
+License     : BSD
+Maintainer  : gspia
+
+= Fcf.Data.Symbol
+
+This might should go to first-class-families.
+
+-}
+
+--------------------------------------------------------------------------------
+
+module Fcf.Data.Symbol
+  where
+
+
+import           Fcf.Core 
+import qualified GHC.TypeLits as TL
+
+
+--------------------------------------------------------------------------------
+
+-- Version should be larger than 9.2.x. Note the two digit space for the
+-- minor.
+#if __GLASGOW_HASKELL__ >= 902
+
+import           Fcf ( type (=<<), Foldr )
+import           Fcf.Data.List ( type (++) )
+
+
+data AppendSymbol :: TL.Symbol -> TL.Symbol -> Exp TL.Symbol
+type instance Eval (AppendSymbol a b) = TL.AppendSymbol a b
+
+data CmpSymbol :: TL.Symbol -> TL.Symbol -> Exp Ordering
+type instance Eval (CmpSymbol a b) = TL.CmpSymbol a b
+
+data CmpChar :: Char -> Char -> Exp Ordering
+type instance Eval (CmpChar a b) = TL.CmpChar a b
+
+data ConsChar :: Char -> TL.Symbol -> Exp TL.Symbol
+type instance Eval (ConsChar a b) = TL.ConsSymbol a b
+
+data UnconsSymbol :: TL.Symbol -> Exp (Maybe (Char, TL.Symbol))
+type instance Eval (UnconsSymbol a) = TL.UnconsSymbol a
+
+data CharToNat :: Char -> Exp TL.Nat
+type instance Eval (CharToNat c) = TL.CharToNat c
+
+data NatToChar :: TL.Nat -> Exp Char
+type instance Eval (NatToChar n) = TL.NatToChar n
+
+
+-- Helper for ToCharList method.
+data HandlePair :: Maybe (Char, TL.Symbol) -> Exp [Char]
+type instance Eval (HandlePair 'Nothing) = '[]
+type instance Eval (HandlePair ('Just '(c, sym))) =
+    Eval ('[c] ++ (Eval (ToCharList sym)))
+
+data ToCharList :: TL.Symbol -> Exp [Char]
+type instance Eval (ToCharList sym) = Eval (HandlePair =<< UnconsSymbol sym)
+
+
+data CharToSymbol :: Char -> Exp TL.Symbol
+type instance Eval (CharToSymbol c) = TL.ConsSymbol c ""
+
+-- > :k! Eval (Concat '[ "aa", "bb", "cc"])
+-- Eval (Concat '[ "aa", "bb", "cc"]) :: TL.Symbol
+-- = "aabbcc"
+-- > :k! Eval (Concat '[ ])
+-- Eval (Concat '[ ]) :: TL.Symbol
+-- = ""
+data Concat :: [TL.Symbol] -> Exp TL.Symbol
+type instance Eval (Concat syms) = Eval (Foldr AppendSymbol "" syms)
+
+
+data ConcatChars :: [Char] -> Exp TL.Symbol
+type instance Eval (ConcatChars chrs) = Eval (Foldr ConsChar "" chrs)
+
+
+--------------------------------------------------------------------------------
+
+#else
+
+--------------------------------------------------------------------------------
+
+
+-- These methods are not available on ghc 9.0 or lower (base 4.16 introduced).
+
+data CmpSymbol :: TL.Symbol -> TL.Symbol -> Exp Ordering
+type instance Eval (CmpSymbol a b) =
+    TL.TypeError ('TL.Text "CmpSymbol in 9.2.x or higher")
+
+data CmpChar :: Char -> Char -> Exp Ordering
+type instance Eval (CmpChar a b) =
+    TL.TypeError ('TL.Text "CmpChar in 9.2.x or higher")
+
+data UnconsSymbol :: TL.Symbol -> Exp (Maybe (Char, TL.Symbol))
+type instance Eval (UnconsSymbol a) =
+    TL.TypeError ('TL.Text "UnconsSymbol in 9.2.x or higher")
+
+data CharToNat :: Char -> Exp TL.Nat
+type instance Eval (CharToNat c) =
+    TL.TypeError ('TL.Text "CharToNat in 9.2.x or higher")
+
+data NatToChar :: TL.Nat -> Exp Char
+type instance Eval (NatToChar n) =
+    TL.TypeError ('TL.Text "NatToChar in 9.2.x or higher")
+
+data ConsChar :: Char -> TL.Symbol -> Exp TL.Symbol
+type instance Eval (ConsChar a b) =
+    TL.TypeError ('TL.Text "ConsChar in 9.2.x or higher")
+
+data ToCharList :: TL.Symbol -> Exp [Char]
+type instance Eval (ToCharList sym) =
+    TL.TypeError ('TL.Text "ToCharList in 9.2.x or higher")
+
+data CharToSymbol :: Char -> Exp TL.Symbol
+type instance Eval (CharToSymbol c) =
+    TL.TypeError ('TL.Text "CharToSymbol in 9.2.x or higher")
+
+data Concat :: [TL.Symbol] -> Exp TL.Symbol
+type instance Eval (Concat lst) =
+    TL.TypeError ('TL.Text "Concat in 9.2.x or higher")
+
+data ConcatChars :: [Char] -> Exp TL.Symbol
+type instance Eval (ConcatChars lst) =
+    TL.TypeError ('TL.Text "ConcatChars in 9.2.x or higher")
+
+#endif
+
+--------------------------------------------------------------------------------
diff --git a/src/Fcf/Data/Text.hs b/src/Fcf/Data/Text.hs
--- a/src/Fcf/Data/Text.hs
+++ b/src/Fcf/Data/Text.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE DataKinds              #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
 {-# LANGUAGE TypeOperators          #-}
@@ -16,22 +14,31 @@
 
 = Fcf.Data.Text
 
-We mimick Data.Text but on type level. The internal representation is based on
-type level lists.
+We mimick Data.Text but on type level. The current internal representation is based
+on type level lists.  The current (as of early 2023) implementation of this
+Fcf.Data.Text will be deprecated and replaced with the contents of Fcf.Data.NewText
+later 2023 as newer version GHC become more widespread.
 
+The old version working with 9.0.x or less will be kept at Fcf.Data.OldText for
+some time.  Similarly, the module Fcf.Data.NewText contains the functions
+and definitions for better Text type, which will be taken into use after some time.
+
 -}
 
 --------------------------------------------------------------------------------
 
 module Fcf.Data.Text
+    {-# WARNING "This still uses the OldText implementaion, which will be replaced with NewText implementation." #-}
     ( Text (..)
 
     -- * Creation
     , Empty
     , Singleton
     , FromList
+    , FromSymbolList
     , ToList
     , ToSymbol
+    , ToSymbolList
 
     -- * Basic Interface
     , Null
@@ -86,6 +93,7 @@
     )
   where
 
+import           GHC.TypeLits (Symbol)
 import qualified GHC.TypeLits as TL
 
 import           Fcf ( If, Eval, Exp, type (=<<), type (@@)
@@ -95,8 +103,6 @@
 import qualified Fcf.Data.List as F
     ( Length, Init, Reverse, Take, Drop, TakeWhile, DropWhile
     , Intercalate, Intersperse, IsPrefixOf, IsSuffixOf, IsInfixOf, Snoc)
-import           Fcf.Data.Symbol (Symbol)
--- import qualified Fcf.Data.Symbol as FS
 
 import qualified Fcf.Class.Functor as F ( FMap )
 
@@ -120,7 +126,7 @@
 
 -- | 'Text' is a data structure, that is, a list to hold type-level symbols of
 -- length one.
-data Text = Text Symbol
+newtype Text = Text Symbol
 
 --------------------------------------------------------------------------------
 
@@ -222,7 +228,7 @@
 -- === __Example__
 --
 -- >>> :kind! Eval (Length =<< Singleton "ab")
--- Eval (Length =<< Singleton "ab") :: Nat
+-- Eval (Length =<< Singleton "ab") :: TL.Natural
 -- = 2
 data Length :: Text -> Exp Nat
 type instance Eval (Length ('Text sym)) = Eval (F.Length (T.ToList sym))
@@ -637,7 +643,7 @@
 -- | Helper for SplitOn
 data SOLoop :: [Symbol] -> ([[Symbol]],[Symbol]) -> Exp [[Symbol]]
 type instance Eval (SOLoop sep '(acc, '[])) = acc
-type instance Eval (SOLoop sep '(acc, (t ': txt))) =
+type instance Eval (SOLoop sep '(acc, t ': txt)) =
     Eval (SOLoop sep =<< First (F.Snoc acc) =<< SOTake sep (t ': txt) '[])
 
 
@@ -665,7 +671,7 @@
 -- | Helper for Split
 data SplitLoop :: (Symbol -> Exp Bool) -> ([[Symbol]],[Symbol]) -> Exp [[Symbol]]
 type instance Eval (SplitLoop p '(acc, '[])) = acc
-type instance Eval (SplitLoop p '(acc, (t ': txt))) = 
+type instance Eval (SplitLoop p '(acc, t ': txt)) = 
     Eval (SplitLoop p =<< First (F.Snoc acc) =<< SplitTake p (t ': txt) '[])
 
 
diff --git a/src/Fcf/Data/Text/Internal.hs b/src/Fcf/Data/Text/Internal.hs
--- a/src/Fcf/Data/Text/Internal.hs
+++ b/src/Fcf/Data/Text/Internal.hs
@@ -1,7 +1,5 @@
-{-# LANGUAGE DataKinds              #-}
 {-# LANGUAGE FlexibleInstances      #-}
 {-# LANGUAGE MultiParamTypeClasses  #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
 {-# LANGUAGE TypeOperators          #-}
@@ -20,7 +18,7 @@
 
 This is from https://kcsongor.github.io/symbol-parsing-haskell/
 
-Ks. symbols library
+Please do also check the symbols library at Hackage.
 
 -}
 
@@ -29,7 +27,6 @@
 module Fcf.Data.Text.Internal where
 
 import Data.Char (chr)
--- import Data.Proxy
 
 import qualified GHC.TypeLits as TL
 import qualified Fcf.Data.List as L
@@ -51,7 +48,7 @@
 type family ToList (sym :: TL.Symbol) :: [TL.Symbol] where
     ToList sym = ToList1 sym ""
 
--- Helper. 
+-- Helper.
 data ToSymbol2 :: [TL.Symbol] -> Exp TL.Symbol
 type instance Eval (ToSymbol2 lst) = Eval (Foldr S.Append "" lst)
 
diff --git a/src/Fcf/Data/Tree.hs b/src/Fcf/Data/Tree.hs
--- a/src/Fcf/Data/Tree.hs
+++ b/src/Fcf/Data/Tree.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE DataKinds              #-}
-{-# LANGUAGE PolyKinds              #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE TypeInType             #-}
 {-# LANGUAGE TypeOperators          #-}
@@ -34,9 +32,11 @@
 
 module Fcf.Data.Tree where
 
-import           Fcf as Fcf
+import           Fcf
 import           Fcf.Data.List as Fcf
 
+import           Fcf.Control.Monad as M
+
 --------------------------------------------------------------------------------
 
 -- For the doctests:
@@ -55,6 +55,50 @@
 -- in this module.
 type Forest a = [Tree a]
 
+
+type ExT1r =
+    'Node 1 '[ 'Node 2 '[ 'Node 3 '[ 'Node 4 '[]]], 'Node 5 '[ 'Node 6 '[]]]
+
+type ExTr2 =
+    'Node ('Just 1)
+        '[ 'Node ('Just 2)
+            '[ 'Node ('Just 3)
+                '[ 'Node ('Just 4) '[]]
+             ]
+         , 'Node ('Just 5)
+            '[ 'Node ('Just 6) '[]
+             ]
+         ]
+
+
+-- map for trees
+type instance Eval (Map f ('Node a tr)) = 'Node (f @@ a) (Eval (Map (Map f) tr))
+
+-- pure/return for trees
+type instance Eval (M.Return a) = 'Node a '[]
+
+-- M.<*> instance (applicative)
+type instance Eval ('Node f tfs M.<*> 'Node x txs) =
+    'Node (Eval (f x))
+        (Eval ( Eval (Map (Map f) txs)
+        ++
+          Eval (Map (StarTx ('Node x txs)) tfs)
+          -- (Eval (Map ( M.<*> ('Node x txs)) tfs))
+        ))
+
+-- Helper for M.<*>
+data StarTx :: Tree a -> Tree (a -> Exp b) -> Exp (Tree b)
+type instance Eval (StarTx fa fab) = Eval (fab M.<*> fa)
+
+
+-- :kind! Eval (Sequence ExTr2)
+type instance Eval (Traverse f ('Node x ts)) =
+    Eval (LiftA2 (Pure2 'Node) (Eval (f x)) (Eval (Traverse (Traverse f) ts)))
+
+
+--------------------------------------------------------------------------------
+
+
 -- | Fold a type-level 'Tree'.
 data FoldTree :: (a -> [b] -> Exp b) -> Tree a -> Exp b
 type instance Eval (FoldTree f ('Node a '[])) = Eval (f a '[])
@@ -76,7 +120,7 @@
 -- :}
 --
 -- >>> :kind! Eval (UnfoldTree BuildNode 1)
--- Eval (UnfoldTree BuildNode 1) :: Tree Nat
+-- Eval (UnfoldTree BuildNode 1) :: Tree TL.Natural
 -- = 'Node
 --     1
 --     '[ 'Node 2 '[ 'Node 4 '[], 'Node 5 '[]],
@@ -95,7 +139,7 @@
 -- === __Example__
 --
 -- >>> :kind! Eval (Flatten ('Node 1 '[ 'Node 2 '[ 'Node 3 '[ 'Node 4 '[]]], 'Node 5 '[ 'Node 6 '[]]]))
--- Eval (Flatten ('Node 1 '[ 'Node 2 '[ 'Node 3 '[ 'Node 4 '[]]], 'Node 5 '[ 'Node 6 '[]]])) :: [Nat]
+-- Eval (Flatten ('Node 1 '[ 'Node 2 '[ 'Node 3 '[ 'Node 4 '[]]], 'Node 5 '[ 'Node 6 '[]]])) :: [TL.Natural]
 -- = '[1, 2, 3, 4, 5, 6]
 data Flatten :: Tree a -> Exp [a]
 type instance Eval (Flatten ('Node a fs )) = a ': Eval (ConcatMap Flatten fs)
@@ -127,9 +171,8 @@
 -- === __Example__
 --
 -- >>> :kind! Eval (Levels ('Node 1 '[ 'Node 2 '[ 'Node 3 '[ 'Node 4 '[]]], 'Node 5 '[ 'Node 6 '[]]]))
--- Eval (Levels ('Node 1 '[ 'Node 2 '[ 'Node 3 '[ 'Node 4 '[]]], 'Node 5 '[ 'Node 6 '[]]])) :: [[Nat]]
+-- Eval (Levels ('Node 1 '[ 'Node 2 '[ 'Node 3 '[ 'Node 4 '[]]], 'Node 5 '[ 'Node 6 '[]]])) :: [[TL.Natural]]
 -- = '[ '[1], '[2, 5], '[3, 6], '[4]]
 data Levels :: Tree a -> Exp [[a]]
 type instance Eval (Levels tr) = Eval (Unfoldr SubFLevels '[tr])
-
 
diff --git a/src/Fcf/Data/Tuple.hs b/src/Fcf/Data/Tuple.hs
new file mode 100644
--- /dev/null
+++ b/src/Fcf/Data/Tuple.hs
@@ -0,0 +1,59 @@
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{-|
+Module      : Fcf.Data.Tuple
+Description : Type-level tuple functions
+Copyright   : (c) gspia 2020-
+License     : BSD
+Maintainer  : gspia
+
+= Fcf.Data.Tuple
+
+
+-}
+
+--------------------------------------------------------------------------------
+
+module Fcf.Data.Tuple where
+
+import           Fcf (Eval, Exp)
+
+--------------------------------------------------------------------------------
+
+-- For the doctests:
+
+-- $setup
+-- >>> import qualified GHC.TypeLits as TL
+
+--------------------------------------------------------------------------------
+
+-- | Swap
+--
+-- === __Example__
+--
+-- >>> :kind! Eval (Swap '(1, 2))
+-- Eval (Swap '(1, 2)) :: (TL.Natural, TL.Natural)
+-- = '(2, 1)
+data Swap :: (a, b) -> Exp (b, a)
+type instance Eval (Swap '(a,b)) = '(b,a)
+
+-- | 2-tuple to allow for partial application of 2-tuple at the type level
+data Tuple2 :: a -> b -> Exp (a, b)
+type instance Eval (Tuple2 a b) = '(a,b)
+
+-- | 3-tuple to allow for partial application of 3-tuple at the type level
+data Tuple3 :: a -> b -> c -> Exp (a, b, c)
+type instance Eval (Tuple3 a b c) = '(a,b,c)
+
+-- | 4-tuple to allow for partial application of 4-tuple at the type level
+data Tuple4 :: a -> b -> c -> d -> Exp (a, b, c, d)
+type instance Eval (Tuple4 a b c d) = '(a,b,c,d)
+
+-- | 5-tuple to allow for partial application of 4-tuple at the type level
+data Tuple5 :: a -> b -> c -> d -> e -> Exp (a, b, c, d, e)
+type instance Eval (Tuple5 a b c d e) = '(a,b,c,d,e)
+
diff --git a/test/Test/Alg.hs b/test/Test/Alg.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Alg.hs
@@ -0,0 +1,22 @@
+
+module Test.Alg where
+
+import           Test.Alg.List     as L (spec)
+import           Test.Alg.Morphism as M (spec)
+import           Test.Alg.Nat      as N (spec)
+import           Test.Alg.Other    as O (spec)
+import           Test.Alg.Sort     as So (spec)
+import           Test.Alg.Symbol   as Sy (spec)
+import           Test.Alg.Tree     as T (spec)
+import           Test.Hspec (describe, Spec)
+
+spec :: Spec
+spec = describe "Alg" $ do
+  L.spec
+  M.spec
+  N.spec
+  O.spec
+  So.spec
+  Sy.spec
+  T.spec
+
diff --git a/test/Test/Alg/List.hs b/test/Test/Alg/List.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Alg/List.hs
@@ -0,0 +1,171 @@
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{- 
+In this module, we test mainly Fcf.Alg.List module. In couple of 
+places, we use the "spec" and Reflect. 
+
+Many of the tests are such that if the answer is not correct, the
+whole test module refuses to compile.  Please do try to change some 
+of the values to see. 
+
+Note that in a way, the spec tests are not needed. If testing just 
+the type level behaviour, the module would refuse to compile if 
+test is not ok (and thus, guard the quality earlier than what the 
+test framework can do).  
+
+Anyhow, as these also work as examples, it is probably ok to have different 
+ways of reaching the results. (E.g. to see, how to get the type level 
+values to value level.)
+
+-}
+module Test.Alg.List where
+
+import           Data.Proxy
+import           Data.Type.Equality ((:~:)(Refl))
+import           Test.Hspec (describe, it, shouldBe, Spec)
+
+import           Fcf.Core (Eval)
+import           Fcf.Combinators (type (=<<))
+import           Fcf.Alg.List
+import           Fcf.Alg.Morphism
+import           Fcf.Data.Reflect (fromType)
+
+--------------------------------------------------------------------------------
+
+-- This module won't compile, if the Refl doesn't give the correct answer.
+--
+-- > :kind! Eval (ListToFix '[1,2,3])
+-- Eval (ListToFix '[1,2,3]) :: Fix (ListF TL.Natural)
+-- = 'Fix ('ConsF 1 ('Fix ('ConsF 2 ('Fix ('ConsF 3 ('Fix 'NilF))))))
+_ = Refl :: Eval (ListToFix '[1,2,3])
+  :~: 'Fix ('ConsF 1 ('Fix ('ConsF 2 ('Fix ('ConsF 3 ('Fix 'NilF))))))
+
+
+-- This module won't compile, if the Refl doesn't give the correct answer.
+--  
+-- > :kind! Eval (ListToParaFix '[1,2,3])
+-- Eval (ListToParaFix '[1,2,3]) :: Fix
+--                                    (ListF (TL.Natural, [TL.Natural]))
+-- = 'Fix
+--     ('ConsF
+--        '(1, '[2, 3])
+--        ('Fix ('ConsF '(2, '[3]) ('Fix ('ConsF '(3, '[]) ('Fix 'NilF))))))
+_ = Refl :: Eval (ListToParaFix '[1,2,3])
+  :~: 'Fix ('ConsF
+       '(1, '[2, 3])
+       ('Fix ('ConsF '(2, '[3]) ('Fix ('ConsF '(3, '[]) ('Fix 'NilF))))))
+
+
+-- This module won't compile, if the Refl doesn't give the correct answer.
+--  
+-- > :kind! Eval (Para DedupAlg =<< ListToParaFix '[1,1,3,2,5,1,3,2])
+-- Eval (Para DedupAlg =<< ListToParaFix '[1,1,3,2,5,1,3,2]) :: [TL.Natural]
+-- = '[5, 1, 3, 2]
+_ = Refl :: Eval (Para DedupAlg =<< ListToParaFix '[1,1,3,2,5,1,3,2])
+  :~: '[5, 1, 3, 2]
+
+
+-- This module won't compile, if the Refl doesn't give the correct answer.
+--  
+-- > :kind! Eval (Sliding 3 '[1,2,3,4,5,6])
+-- Eval (Sliding 3 '[1,2,3,4,5,6]) :: [[TL.Natural]]
+-- = '[ '[1, 2, 3], '[2, 3, 4], '[3, 4, 5], '[4, 5, 6], '[5, 6], '[6]]
+_ = Refl :: Eval (Sliding 3 '[1,2,3,4,5,6])
+  :~: '[ '[1, 2, 3], '[2, 3, 4], '[3, 4, 5], '[4, 5, 6], '[5, 6], '[6]]
+
+
+-- This module won't compile, if the Refl doesn't give the correct answer.
+--  
+-- > :kind! Eval (Evens =<< RunInc 8)
+-- Eval (Evens =<< RunInc 8) :: [TL.Natural]
+-- = '[2, 4, 6, 8]
+_ = Refl :: Eval (Evens =<< RunInc 8)
+  :~: '[2, 4, 6, 8]
+
+
+-- This module won't compile, if the Refl doesn't give the correct answer.
+--  
+-- > :kind! Eval (RunInc 8)
+-- Eval (RunInc 8) :: [TL.Natural]
+-- = '[1, 2, 3, 4, 5, 6, 7, 8]
+_ = Refl :: Eval (RunInc 8)
+  :~: '[1, 2, 3, 4, 5, 6, 7, 8]
+
+
+-- This module won't compile, if the Refl doesn't give the correct answer.
+--  
+-- > :kind! Eval (MToN 1 3)
+-- Eval (MToN 1 3) :: [TL.Natural]
+-- = '[1, 2, 3]
+_ = Refl :: Eval (MToN 1 3)
+  :~: '[1, 2, 3]
+
+-- This module won't compile, if the Refl doesn't give the correct answer.
+--  
+-- > :kind! Eval (ToList 1)
+-- Eval (ToList 1) :: [TL.Natural]
+-- = '[1]
+_ = Refl :: Eval (ToList 1)
+  :~: '[1]
+
+  
+--------------------------------------------------------------------------------
+
+-- > :kind! Eval (Cata LenAlg =<< ListToFix '[1,2,3])
+-- Eval (Cata LenAlg =<< ListToFix '[1,2,3]) :: TL.Natural
+-- = 3
+
+-- > :kind! Eval (Cata SumAlg =<< ListToFix '[1,2,3,4])
+-- Eval (Cata SumAlg =<< ListToFix '[1,2,3,4]) :: TL.Natural
+-- = 10
+
+-- > :kind! Eval (Cata ProdAlg =<< ListToFix '[1,2,3,4])
+-- Eval (Cata ProdAlg =<< ListToFix '[1,2,3,4]) :: TL.Natural
+-- = 24
+
+-- > :kind! Eval (Sum '[1,2,3])
+-- Eval (Sum '[1,2,3]) :: TL.Natural
+-- = 6
+
+-- > :kind! Eval (Equal '[1,2,3] '[1,2,3])
+-- Eval (Equal '[1,2,3] '[1,2,3]) :: Bool
+-- = 'True
+
+-- > :kind! Eval (Equal '[1,2,3] '[1,3,2])
+-- Eval (Equal '[1,2,3] '[1,3,2]) :: Bool
+-- = 'False
+
+spec :: Spec
+spec = describe "List" $ do
+  it "Cata LenAlg" $ do
+    let test :: forall r. (r ~ Eval (Cata LenAlg =<< ListToFix '[1,2,3])) => Int
+        test = fromType (Proxy @r)
+    test `shouldBe` 3
+  it "Cata SumAlg" $ do
+    let test :: forall r. (r ~ Eval (Cata SumAlg =<< ListToFix '[1,2,3,4])) => Int
+        test = fromType (Proxy @r)
+    test `shouldBe` 10
+  it "Cata ProdAlg" $ do
+    let test :: forall r. (r ~ Eval (Cata ProdAlg =<< ListToFix '[1,2,3,4])) => Int
+        test = fromType (Proxy @r)
+    test `shouldBe` 24
+  it "Sum" $ do
+    let test :: forall r. (r ~ Eval (Sum '[1,2,3])) => Int
+        test = fromType (Proxy @r)
+    test `shouldBe` 6
+  it "Equal, True" $ do
+    let test :: forall r. (r ~ Eval (Equal '[1,2,3] '[1,2,3])) => Bool
+        test = fromType (Proxy @r)
+    test `shouldBe` True
+  it "Equal, False" $ do
+    let test :: forall r. (r ~ Eval (Equal '[1,2,3] '[1,3,2])) => Bool
+        test = fromType (Proxy @r)
+    test `shouldBe` False
+
diff --git a/test/Test/Alg/Morphism.hs b/test/Test/Alg/Morphism.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Alg/Morphism.hs
@@ -0,0 +1,85 @@
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{- 
+In this module, we test mainly Fcf.Alg.Morphism module. In couple of 
+places, we use the "spec" and Reflect. 
+
+Many of the tests are such that if the answer is not correct, the
+whole test module refuses to compile.  Please do try to change some 
+of the values to see. 
+
+Note that in a way, the spec tests are not needed. If testing just 
+the type level behaviour, the module would refuse to compile if 
+test is not ok (and thus, guard the quality earlier than what the 
+test framework can do).  
+
+Anyhow, as these also work as examples, it is probably ok to have different 
+ways of reaching the results. (E.g. to see, how to get the type level 
+values to value level.)
+
+-}
+module Test.Alg.Morphism where
+
+import qualified GHC.TypeLits as TL
+
+import           Data.Proxy
+import           Data.Type.Equality ((:~:)(Refl))
+import           Test.Hspec (describe, it, shouldBe, Spec)
+
+import           Fcf.Core (Eval)
+import           Fcf.Utils (If)
+import           Fcf.Alg.List
+import           Fcf.Alg.Morphism
+import           Fcf.Data.Nat
+import           Fcf.Data.Reflect (fromType)
+
+--------------------------------------------------------------------------------
+
+-- For the Ana and Hylo tests made below.
+data NToOneCoA :: CoAlgebra (ListF Nat) Nat
+type instance Eval (NToOneCoA b) =
+  If (Eval (b < 1) )
+      'NilF
+      ('ConsF b ( b TL.- 1))
+
+
+-- This module won't compile, if the Refl doesn't give the correct answer.
+--
+-- > :kind! Eval (Ana NToOneCoA 3)
+-- Eval (Ana NToOneCoA 3) :: Fix (ListF TL.Natural)
+-- = 'Fix ('ConsF 3 ('Fix ('ConsF 2 ('Fix ('ConsF 1 ('Fix 'NilF))))))
+_ = Refl :: Eval (Ana NToOneCoA 3)
+  :~: 'Fix ('ConsF 3 ('Fix ('ConsF 2 ('Fix ('ConsF 1 ('Fix 'NilF))))))
+
+-- > :kind! Eval (Second ((+) 1) '("a",3))
+-- Eval (Second ((+) 1) '("a",3)) :: (TL.Symbol, TL.Natural)
+-- = '("a", 4)
+_ = Refl :: Eval (Second ((+) 1) '("a",3))
+  :~: '("a", 4)
+
+
+-- > :kind! Eval (Hylo SumAlg NToOneCoA 5)
+-- Eval (Hylo SumAlg NToOneCoA 5) :: TL.Natural
+-- = 15
+
+-- > :kind! Eval (First ((+) 1) '(3,"a"))
+-- Eval (First ((+) 1) '(3,"a")) :: (TL.Natural, TL.Symbol)
+-- = '(4, "a")
+
+spec :: Spec
+spec = describe "Morphism" $ do
+  it "Hylo SumAlg" $ do
+    let test :: forall r. (r ~ Eval (Hylo SumAlg NToOneCoA 5)) => Int
+        test = fromType (Proxy @r)
+    test `shouldBe` 15
+  it "First" $ do
+    let test :: forall r. (r ~ Eval (First ((+) 1) '(3,"a"))) => (Int, String)
+        test = fromType (Proxy @r)
+    test `shouldBe` (4,"a")
diff --git a/test/Test/Alg/Nat.hs b/test/Test/Alg/Nat.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Alg/Nat.hs
@@ -0,0 +1,66 @@
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{- 
+In this module, we test mainly Fcf.Alg.Nat module. In couple of 
+places, we use the "spec" and Reflect. 
+
+Many of the tests are such that if the answer is not correct, the
+whole test module refuses to compile.  Please do try to change some 
+of the values to see. 
+
+Note that in a way, the spec tests are not needed. If testing just 
+the type level behaviour, the module would refuse to compile if 
+test is not ok (and thus, guard the quality earlier than what the 
+test framework can do).  
+
+Anyhow, as these also work as examples, it is probably ok to have different 
+ways of reaching the results. (E.g. to see, how to get the type level 
+values to value level.)
+
+-}
+
+module Test.Alg.Nat where
+
+import           Data.Proxy
+import           Data.Type.Equality ((:~:)(Refl))
+import           Test.Hspec (describe, it, shouldBe, Spec)
+
+import           Fcf.Core (Eval)
+import           Fcf.Alg.Nat
+import           Fcf.Data.Reflect (fromType)
+
+-- > :kind! Eval (2 == 2)
+-- Eval (2 == 2) :: Bool
+-- = 'True
+_ = Refl :: Eval (2==2) :~: 'True
+
+-- > :kind! Eval (2 == 3)
+-- Eval (2 == 3) :: Bool
+-- = 'False
+_ = Refl :: Eval (2==3) :~: 'False
+
+
+-- > :kind! Eval (2 /= 2)
+-- Eval (2 /= 2) :: Bool
+-- = 'False
+--
+-- > :kind! Eval (2 /= 3)
+-- Eval (2 /= 3) :: Bool
+-- = 'True
+spec :: Spec
+spec = describe "Nat" $ do
+  it "In-equality, false" $ do
+    let test :: forall r. (r ~ Eval (2 /= 2)) => Bool
+        test = fromType (Proxy @r)
+    test `shouldBe` False
+  it "In-equality, true" $ do
+    let test :: forall r. (r ~ Eval (2 /= 3)) => Bool
+        test = fromType (Proxy @r)
+    test `shouldBe` True
diff --git a/test/Test/Alg/Other.hs b/test/Test/Alg/Other.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Alg/Other.hs
@@ -0,0 +1,54 @@
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{- 
+In this module, we test mainly Fcf.Alg.Other module. In couple of 
+places, we use the "spec" and Reflect. 
+
+Many of the tests are such that if the answer is not correct, the
+whole test module refuses to compile.  Please do try to change some 
+of the values to see. 
+
+Note that in a way, the spec tests are not needed. If testing just 
+the type level behaviour, the module would refuse to compile if 
+test is not ok (and thus, guard the quality earlier than what the 
+test framework can do).  
+
+Anyhow, as these also work as examples, it is probably ok to have different 
+ways of reaching the results. (E.g. to see, how to get the type level 
+values to value level.)
+
+-}
+module Test.Alg.Other where
+
+import           Data.Proxy
+import           Data.Type.Equality ((:~:)(Refl))
+import           Test.Hspec (describe, it, shouldBe, Spec)
+
+import           Fcf.Core (Eval)
+import           Fcf.Alg.Other
+import           Fcf.Data.Reflect (fromType)
+
+-- > :kind! Eval (PairMaybeToMaybePair '( 'Just "txt", 'Just 1))
+-- Eval (PairMaybeToMaybePair '( 'Just "txt", 'Just 1)) :: Maybe
+--                                                           (Symbol, TL.Natural)
+-- = 'Just '("txt", 1)
+_ = Refl :: Eval (PairMaybeToMaybePair '( 'Just "txt", 'Just 1)) 
+  :~: 'Just '("txt", 1)
+
+
+-- > :kind! Eval (Id "id")
+-- Eval (Id "id") :: Symbol
+-- = "id"
+spec :: Spec
+spec = describe "Other" $ do
+  it "Id" $ do
+    let test :: forall r. (r ~ Eval (Id "id")) => String
+        test = fromType (Proxy @r)
+    test `shouldBe` "id"
diff --git a/test/Test/Alg/Sort.hs b/test/Test/Alg/Sort.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Alg/Sort.hs
@@ -0,0 +1,56 @@
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{- 
+In this module, we test mainly Fcf.Alg.Sort module. In couple of 
+places, we use the "spec" and Reflect. 
+
+Many of the tests are such that if the answer is not correct, the
+whole test module refuses to compile.  Please do try to change some 
+of the values to see. 
+
+Note that in a way, the spec tests are not needed. If testing just 
+the type level behaviour, the module would refuse to compile if 
+test is not ok (and thus, guard the quality earlier than what the 
+test framework can do).  
+
+Anyhow, as these also work as examples, it is probably ok to have different 
+ways of reaching the results. (E.g. to see, how to get the type level 
+values to value level.)
+
+-}
+
+module Test.Alg.Sort where
+
+import           Data.Proxy
+import           Data.Type.Equality ((:~:)(Refl))
+import           Test.Hspec (describe, it, shouldBe, Spec)
+
+import           Fcf.Core (Eval)
+import           Fcf.Alg.Sort
+import qualified Fcf.Alg.Symbol as S ( type (<) )
+import qualified Fcf.Data.Nat as N ( type (<) )
+import           Fcf.Data.Reflect (fromType)
+
+-- > :kind! Eval (Qsort (N.<) '[5,3,1,9,4,6,3])
+-- Eval (Qsort (N.<) '[5,3,1,9,4,6,3]) :: [TL.Natural]
+-- = '[1, 3, 3, 4, 5, 6, 9]
+spec :: Spec
+spec = describe "Sort" $ do
+  it "QSort (<)" $ do
+    let test :: forall r. (r ~ Eval (Qsort (N.<) '[5,3,1,9,4,6,3])) => [Int]
+        test = fromType (Proxy @r)
+    test `shouldBe` [1, 3, 3, 4, 5, 6, 9]
+
+-- > :kind! Eval (Qsort (S.<) '[ "bb", "e", "a", "e", "d" ])
+-- Eval (Qsort (S.<) '[ "bb", "e", "a", "e", "d" ]) :: [Symbol]
+-- = '["a", "bb", "d", "e", "e"]
+_ = Refl :: Eval (Qsort (S.<) '[ "bb", "e", "a", "e", "d" ])
+  :~: '["a", "bb", "d", "e", "e"]
+
diff --git a/test/Test/Alg/Symbol.hs b/test/Test/Alg/Symbol.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Alg/Symbol.hs
@@ -0,0 +1,157 @@
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{- 
+In this module, we test mainly Fcf.Alg.Symbol module. In couple of 
+places, we use the "spec" and Reflect. 
+
+Many of the tests are such that if the answer is not correct, the
+whole test module refuses to compile.  Please do try to change some 
+of the values to see. 
+
+Note that in a way, the spec tests are not needed. If testing just 
+the type level behaviour, the module would refuse to compile if 
+test is not ok (and thus, guard the quality earlier than what the 
+test framework can do).  
+
+Anyhow, as these also work as examples, it is probably ok to have different 
+ways of reaching the results. (E.g. to see, how to get the type level 
+values to value level.)
+
+-}
+
+module Test.Alg.Symbol where
+
+import           Data.Proxy
+import           Data.Type.Equality ((:~:)(Refl))
+import           Test.Hspec (describe, it, shouldBe, Spec)
+
+import           Fcf.Core (Eval)
+import           Fcf.Alg.Symbol
+import           Fcf.Data.Reflect (fromType)
+
+-- > :kind! Eval (Append "hmm" " ok")
+-- Eval (Append "hmm" " ok") :: Symbol
+-- = "hmm ok"
+_ = Refl :: Eval (Append "hmm" " ok") :~: "hmm ok"
+
+-- > :kind! Eval (Intercalate "+" '["aa", "bb", "cc"])
+-- Eval (Intercalate "+" '["aa", "bb", "cc"]) :: Symbol
+-- = "aa+bb+cc"
+_ = Refl :: Eval (Intercalate "+" '["aa", "bb", "cc"]) :~: "aa+bb+cc"
+
+-- > :kind! Eval (Intercalate "+" '["aa"])
+-- Eval (Intercalate "+" '["aa"]) :: Symbol
+-- = "aa"
+_ = Refl :: Eval (Intercalate "+" '["aa"]) :~: "aa"
+
+-- > :kind! Eval (Intercalate "+" '[])
+-- Eval (Intercalate "+" '[]) :: Symbol
+-- = ""
+_ = Refl :: Eval (Intercalate "+" '[]) :~: ""
+
+-- > :kind! Eval (IsSpace "a")
+-- Eval (IsSpace "a") :: Bool
+-- = 'False
+_ = Refl :: Eval (IsSpace "a") :~: 'False
+--
+-- > :kind! Eval (IsSpace " ")
+-- Eval (IsSpace " ") :: Bool
+-- = 'True
+_ = Refl :: Eval (IsSpace " ") :~: 'True
+
+-- > :kind! Eval (IsNewLine "a")
+-- Eval (IsNewLine "a") :: Bool
+-- = 'False
+_ = Refl :: Eval (IsNewLine "a") :~: 'False
+
+-- > :kind! Eval (IsNewLine "\n")
+-- Eval (IsNewLine "\n") :: Bool
+-- = 'True
+_ = Refl :: Eval (IsNewLine "\n") :~: 'True
+
+-- > :kind! Eval (IsTab "a")
+-- Eval (IsTab "a") :: Bool
+-- = 'False
+_ = Refl :: Eval (IsTab "a") :~: 'False
+--
+-- > :kind! Eval (IsTab "\t")
+-- Eval (IsTab "\t") :: Bool
+-- = 'True
+_ = Refl :: Eval (IsTab "\t") :~: 'True
+
+-- > :kind! Eval (IsSpaceDelim "a")
+-- Eval (IsSpaceDelim "a") :: Bool
+-- = 'False
+_ = Refl :: Eval (IsSpaceDelim "a") :~: 'False
+--
+-- > :kind! Eval (IsSpaceDelim "\n")
+-- Eval (IsSpaceDelim "\n") :: Bool
+-- = 'True
+_ = Refl :: Eval (IsSpaceDelim "\n") :~: 'True
+
+-- > :kind! Eval (IsDigit "3")
+-- Eval (IsDigit "3") :: Bool
+-- = 'True
+_ = Refl :: Eval (IsDigit "3") :~: 'True
+--
+-- > :kind! Eval (IsDigit "a")
+-- Eval (IsDigit "a") :: Bool
+-- = 'False
+_ = Refl :: Eval (IsDigit "a") :~: 'False
+
+-- > :kind! Eval (SymbolOrd "a" "b")
+-- Eval (SymbolOrd "a" "b") :: Ordering
+-- = 'LT
+_ = Refl :: Eval (SymbolOrd "a" "b") :~: 'LT
+
+--------------------------------------------------------------------------------
+
+-- > :kind! Eval ("b" <= "a")
+-- Eval ("b" <= "a") :: Bool
+-- = 'False
+--
+-- > :kind! Eval ("b" >= "a")
+-- Eval ("b" >= "a") :: Bool
+-- = 'True
+--
+-- > :kind! Eval ("a" < "b")
+-- Eval ("a" < "b") :: Bool
+-- = 'True
+--
+-- > :kind! Eval ("b" > "a")
+-- Eval ("b" > "a") :: Bool
+-- = 'True
+--
+-- > :kind! Eval ("b" == "a")
+-- Eval ("b" == "a") :: Bool
+-- = 'False
+spec :: Spec
+spec = describe "Symbol" $ do
+  it "<=" $ do
+    let test :: forall r. (r ~ Eval ("b" <= "a")) => Bool
+        test = fromType (Proxy @r)
+    test `shouldBe` False
+  it ">=" $ do
+    let test :: forall r. (r ~ Eval ("b" >= "a")) => Bool
+        test = fromType (Proxy @r)
+    test `shouldBe` True
+  it "<" $ do
+    let test :: forall r. (r ~ Eval ("b" < "a")) => Bool
+        test = fromType (Proxy @r)
+    test `shouldBe` False
+  it ">" $ do
+    let test :: forall r. (r ~ Eval ("b" > "a")) => Bool
+        test = fromType (Proxy @r)
+    test `shouldBe` True
+  it "==" $ do
+    let test :: forall r. (r ~ Eval ("b" == "a")) => Bool
+        test = fromType (Proxy @r)
+    test `shouldBe` False
+    
diff --git a/test/Test/Alg/Tree.hs b/test/Test/Alg/Tree.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Alg/Tree.hs
@@ -0,0 +1,129 @@
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+{- 
+In this module, we test mainly Fcf.Alg.Tree module. In couple of 
+places, we use the "spec" and Reflect. 
+
+Many of the tests are such that if the answer is not correct, the
+whole test module refuses to compile.  Please do try to change some 
+of the values to see. 
+
+Note that in a way, the spec tests are not needed. If testing just 
+the type level behaviour, the module would refuse to compile if 
+test is not ok (and thus, guard the quality earlier than what the 
+test framework can do).  
+
+Anyhow, as these also work as examples, it is probably ok to have different 
+ways of reaching the results. (E.g. to see, how to get the type level 
+values to value level.)
+
+-}
+
+module Test.Alg.Tree where
+
+import qualified GHC.TypeLits as TL
+
+import           Data.Proxy
+import           Data.Type.Equality ((:~:)(Refl))
+import           Test.Hspec (describe, it, shouldBe, Spec)
+
+import           Fcf.Data.Nat
+
+import           Fcf.Alg.Morphism 
+import           Fcf.Alg.Tree
+import           Fcf.Combinators (type (=<<))
+import           Fcf.Core (Eval, Exp)
+import           Fcf.Utils (If)
+import           Fcf.Data.Reflect (fromType)
+import           Fcf.Data.Tree
+
+data BuildNode :: Nat -> Exp (Nat,[Nat])
+type instance Eval (BuildNode x) =
+    If (Eval ((2 TL.* x TL.+ 1) >= 8))
+        '(x, '[])
+        '(x, '[ 2 TL.* x, (2 TL.* x) TL.+ 1 ])
+
+-- > :kind! Eval (Size =<< UnfoldTree BuildNode 1)
+-- Eval (Size =<< UnfoldTree BuildNode 1) :: TL.Natural
+-- = 7
+_ = Refl :: Eval (Size =<< UnfoldTree BuildNode 1) :~: 7
+
+
+-- :kind! Eval (Ana BuildNodeCoA 1)
+-- :kind! Eval (Hylo CountNodesAlg BuildNodeCoA 1)
+
+
+-- > :kind! Eval (Sizes =<< Ana BuildNodeCoA 1)
+-- Eval (Sizes =<< Ana BuildNodeCoA 1) :: Fix
+--                                          (AnnF (TreeF TL.Natural) TL.Natural)
+-- = 'Fix
+--     ('AnnF
+--        '( 'NodeF
+--             1
+--             '[ 'Fix
+--                  ('AnnF
+--                     '( 'NodeF
+--                          2
+--                          '[ 'Fix ('AnnF '( 'NodeF 4 '[], 1)),
+--                             'Fix ('AnnF '( 'NodeF 5 '[], 1))],
+--                        3)),
+--                'Fix
+--                  ('AnnF
+--                     '( 'NodeF
+--                          3
+--                          '[ 'Fix ('AnnF '( 'NodeF 6 '[], 1)),
+--                             'Fix ('AnnF '( 'NodeF 7 '[], 1))],
+--                        3))],
+--           7))
+_ = Refl :: Eval (Sizes =<< Ana BuildNodeCoA 1)
+  :~: 'Fix
+    ('AnnF
+       '( 'NodeF
+            1
+            '[ 'Fix
+                 ('AnnF
+                    '( 'NodeF
+                         2
+                         '[ 'Fix ('AnnF '( 'NodeF 4 '[], 1)),
+                            'Fix ('AnnF '( 'NodeF 5 '[], 1))],
+                       3)),
+               'Fix
+                 ('AnnF
+                    '( 'NodeF
+                         3
+                         '[ 'Fix ('AnnF '( 'NodeF 6 '[], 1)),
+                            'Fix ('AnnF '( 'NodeF 7 '[], 1))],
+                       3))],
+          7))
+
+-- Turning this off, because of the slowness. In practice, this would
+-- also require turning on ghc-options (-freduction-depth=0). 
+-- Please, do try on ghci.
+-- > :kind! Eval (FibHisto 100)
+-- Eval (FibHisto 100) :: TL.Natural
+-- = 354224848179261915075
+-- _ = Refl :: Eval (FibHisto 100) :~: 354224848179261915075
+
+-- > :kind! Eval (FibHylo 10)
+-- Eval (FibHylo 10) :: TL.Natural
+-- = 55
+spec :: Spec
+spec = describe "Tree" $ do
+  it "FibHisto" $ do
+    let test :: forall r. (r ~ Eval (FibHylo 10)) => Int
+        test = fromType (Proxy @r)
+    test `shouldBe` 55
+  -- The following is very slow and would require turning on ghc-options
+  -- (-freduction-depth=0).  
+  -- it "FibHisto" $ do
+  --   let test :: forall r. (r ~ Eval (FibHisto 100)) => Integer
+  --       test = fromType (Proxy @r)
+  --   test `shouldBe` 354224848179261915075
+
diff --git a/test/Test/Control.hs b/test/Test/Control.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Control.hs
@@ -0,0 +1,9 @@
+
+module Test.Control where
+
+import           Test.Control.Monad as M (spec)
+import           Test.Hspec (describe, Spec)
+
+spec :: Spec
+spec = describe "Control" $ do
+  M.spec
diff --git a/test/Test/Control/Monad.hs b/test/Test/Control/Monad.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Control/Monad.hs
@@ -0,0 +1,140 @@
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE RankNTypes             #-}
+{-# LANGUAGE DataKinds              #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE TupleSections          #-}
+{-# LANGUAGE AllowAmbiguousTypes    #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+module Test.Control.Monad where
+
+import           Data.Functor ((<&>))
+import           Data.Proxy
+import           Control.Applicative
+import           Test.Hspec (describe, it, shouldBe, Spec)
+import           GHC.TypeLits (Nat, Symbol)
+
+import           Fcf hiding (type (<*>))
+import           Fcf.Data.Tuple
+import           Fcf.Data.List (Cons)
+import           Fcf.Control.Monad
+import           Fcf.Class.Monoid (type (.<>))
+import           Fcf.Data.Reflect (fromType)
+
+-- data TraversableTest = TraversableTest Symbol [(Symbol, Nat)]
+
+data SafeMinus :: Nat -> Nat -> Exp (Either Symbol Nat)
+type instance Eval (SafeMinus a b) = If (Eval (a >= b)) ('Right (Eval (a - b))) ('Left "Nat cannot be negative")
+
+
+spec :: Spec
+spec = describe "Monad" $ do
+  it "liftA2 (,) instance" $ do
+    let test :: forall r. (r ~ Eval (LiftA2 Tuple2 '("hello ", 5) '("world", 6))) => (String, (Int, Int))
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      liftA2 (,) ("hello ", 5) ("world", 6)
+  it "<*> (,) instance" $ do
+    let test :: forall r. (r ~ Eval ('("hello ", (+) 15) <*> '("world!", 2002))) => (String,Int)
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      ("hello ", (+) 15) <*> ("world!", 2002)
+  it ">>= (,) instance" $ do
+    let test :: forall r. (r ~ Eval ('("age", 5) >>= (Return <=< (+) 1))) => (String,Int)
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      (("age",5) <&> (+) 1)
+      -- Above was suggested by hlint for the following:
+      -- (("age",5) >>= return . (+) 1)
+  it "liftA3 (,,) instance" $ do
+    let test :: forall r. (r ~ Eval (LiftA3 Tuple3 '("hello ", "<", 6) '("world", " ", 8) '("!", ">", 10))) => (String, String, (Int, Int, Int))
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      liftA3 (,,) ("hello ","<",6) ("world"," ",8) ("!",">",10)
+  it ">>= (,,) instance" $ do
+    let test :: forall r. (r ~ Eval ('("he","wo",19) >>= (Tuple3 "llo" "rld" <=< Flip (-) 1))) => (String,String,Int)
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      (("he","wo",19) >>= ("llo","rld",) . flip (-) 1)
+  it "liftA4 Either instance test Left" $ do
+    let test :: forall r. (r ~ Eval (LiftA4 Tuple4 ('Right 5) ('Right 6) ('Right 7) ('Left "fail"))) => Either String (Int,Int,Int,Int)
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      (,,,) <$> Right 5 <*> Right 6 <*> Right 7 <*> Left "fail"
+  it "liftA4 Either instance test Right" $ do
+    let test :: forall r. (r ~ Eval (LiftA4 Tuple4 ('Right 5) ('Right 6) ('Right 7) ('Right 0))) => Either String (Int,Int,Int,Int)
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      (,,,) <$> Right 5 <*> Right 6 <*> Right 7 <*> Right 0
+  it "Traversable Either instance, test with MapM" $ do
+    let typeLevelFunc :: forall (list :: [(Symbol,Nat)]) r. 
+            (r ~ Eval 
+              (Map 
+                (Flip Cons '[] <=< Tuple2 "test") 
+                (MapM
+                  (MapM (Flip SafeMinus 1))
+                  @@ list
+                )
+              )
+            ) => Proxy r
+        typeLevelFunc = Proxy @r
+    let safeMinus a b = if a >= b then Right (a - b) else Left "Nat cannot be negative"
+    let valTest :: [(String,Int)] -> Either String [(String, [(String, Int)])]
+        valTest list = fmap (flip (:) [] . ("test",)) (mapM (mapM (`safeMinus` 1)) list)
+    fromType (typeLevelFunc @'[ '("key1",1), '("key2",2)])
+      `shouldBe` 
+      valTest [("key1",1),("key2",2)]
+    fromType (typeLevelFunc @'[ '("key1",0), '("key2",2)])
+      `shouldBe` 
+      valTest [("key1",0),("key2",2)]
+  it "liftA5 [] instance" $ do
+    let test :: forall r. (r ~ Eval (LiftA5 Tuple5 '[1,5] '[2,4] '[6,7,8] '[9,11,10] '[0] )) => [(Int,Int,Int,Int,Int)]
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      (,,,,) <$> [1,5] <*> [2,4] <*> [6,7,8] <*> [9,11,10] <*> [0]
+  it "<*> [] instance" $ do
+    let test :: forall r. (r ~ Eval ('[(+) 1,(+) 2] <*> '[3,4])) => [Int]
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      [(+) 1,(+) 2] <*> [3,4]
+  it ">>= [] instance" $ do
+    let test :: forall r. (r ~ Eval ('[5,6,7] >>= Plus2M)) => [Int]
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      ([5,6,7] >>= (\n -> [n + 2, n + 3]))
+  it ">>= Maybe instance test Just" $ do
+    let test :: forall r. (r ~ Eval ('Just "hello" >>= (Return <=< Flip (.<>) " world"))) => Maybe String
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      (Just "hello" <&> flip (<>) " world")
+      -- Above was suggested by hlint for the following:
+      -- (Just "hello" >>= (return . flip (<>) " world"))
+  it ">>= Maybe instance test Nothing" $ do
+    let test :: forall r. (r ~ Eval ('Nothing >>= (Return <=< Flip (.<>) " world"))) => Maybe String
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      (Nothing <&> flip (<>) " world")
+      -- Above was suggested by hlint for the following:
+      -- (Nothing >>= (return . flip (<>) " world"))
+  it ">> Maybe instance" $ do
+    let test :: forall r. (r ~ Eval ('Just 5 >> 'Just "hello world")) => Maybe String
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      (Just (5 :: Int) >> Just "hello world")
diff --git a/test/Test/Data.hs b/test/Test/Data.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Data.hs
@@ -0,0 +1,12 @@
+
+module Test.Data where
+
+import           Test.Data.Reflect as R (spec)
+import           Test.Data.Set as S (spec)
+import           Test.Hspec (describe, Spec)
+
+spec :: Spec
+spec = describe "Data" $ do 
+  R.spec
+  S.spec
+
diff --git a/test/Test/Data/Reflect.hs b/test/Test/Data/Reflect.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Data/Reflect.hs
@@ -0,0 +1,328 @@
+{-# LANGUAGE CPP                    #-}
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE RankNTypes             #-}
+{-# LANGUAGE DataKinds              #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+module Test.Data.Reflect where
+
+import qualified Data.IntMap as IM
+import qualified Data.Map as DM
+import qualified Data.Set as DS
+import qualified Data.Tree as DT
+import qualified Data.Text as DTxt
+import qualified GHC.TypeLits as TL
+import           Data.Proxy
+import           Test.Hspec (describe, it, shouldBe, Spec)
+
+import           Fcf (Eval, type (=<<))
+import qualified Fcf.Data.Set as FS
+import qualified Fcf.Data.NatMap as FNM
+import qualified Fcf.Data.MapC as FNMC
+#if __GLASGOW_HASKELL__ >= 902
+import qualified Fcf.Data.NewText as FTxt
+#endif
+import qualified Fcf.Data.Tree as FT
+import           Fcf.Data.Reflect
+
+--------------------------------------------------------------------------------
+
+spec :: Spec
+spec = describe "Reflect" $ do
+  specTrees
+  specMaybe
+  specEither
+  specMaybeEither
+  specStructures
+  specShowTypeable
+  specErrorMessage
+  
+specBool :: Spec
+specBool = describe "Bool" $ do
+  it "Bool, True" $ do
+    let test :: forall r. (r ~ 'True) => Bool
+        test = fromType (Proxy @r)
+    test `shouldBe` True
+  it "Bool, False" $ do
+    let test :: forall r. (r ~ 'False) => Bool
+        test = fromType (Proxy @r)
+    test `shouldBe` False
+
+specMaybe :: Spec
+specMaybe = describe "Maybe" $ do
+  it "Maybe Int, Just" $ do
+    let test :: forall r. (r ~ 'Just 5) 
+             => Maybe Int
+        test = fromType (Proxy @r)
+    test `shouldBe` Just 5
+  it "Maybe Int, Nothing" $ do
+    let test :: forall r. (r ~ 'Nothing) 
+             => Maybe Int
+        test = fromType (Proxy @r)
+    test `shouldBe` Nothing
+  it "Maybe String, Just" $ do
+    let test :: forall r. (r ~ 'Just "just") 
+             => Maybe String
+        test = fromType (Proxy @r)
+    test `shouldBe` Just "just"
+  it "Maybe String, Nothing" $ do
+    let test :: forall r. (r ~ 'Nothing) 
+             => Maybe String
+        test = fromType (Proxy @r)
+    test `shouldBe` Nothing
+
+specEither :: Spec
+specEither = describe "Either" $ do
+  it "Either Int String, Left" $ do
+    let test :: forall r. (r ~ 'Left 5) 
+             => Either Int String
+        test = fromType (Proxy @r)
+    test `shouldBe` Left 5
+  it "Either Int String, Right" $ do
+    let test :: forall r. (r ~ 'Right "right") 
+             => Either Int String
+        test = fromType (Proxy @r)
+    test `shouldBe` Right "right"
+  it "Either Int (Either Int String), Right Right" $ do
+    let test :: forall r. (r ~ 'Right ('Right "right"))
+             => Either Int (Either Int String)
+        test = fromType (Proxy @r)
+    test `shouldBe` Right (Right "right")
+  it "Either (Either Int String) String, Left Left" $ do
+    let test :: forall r. (r ~ 'Left ('Left 5)) 
+             => Either (Either Int String) String
+        test = fromType (Proxy @r)
+    test `shouldBe` Left (Left 5)
+
+specMaybeEither :: Spec
+specMaybeEither = describe "Maybe Either and Either Maybe" $ do
+  it "Either Int (Maybe String), Right Just" $ do
+    let test :: forall r. (r ~ 'Right ('Just "right just"))
+             => Either Int (Maybe String)
+        test = fromType (Proxy @r)
+    test `shouldBe` Right (Just "right just")
+  it "Either Int (Maybe String), Right Nothing" $ do
+    let test :: forall r. (r ~ 'Right 'Nothing)
+             => Either Int (Maybe String)
+        test = fromType (Proxy @r)
+    test `shouldBe` Right Nothing
+  it "Maybe (Either Int String), Just Right" $ do
+    let test :: forall r. (r ~ 'Just ('Right "just right"))
+             => Maybe (Either Int String)
+        test = fromType (Proxy @r)
+    test `shouldBe` Just (Right "just right")
+  it "Maybe (Either Int String), Nothing" $ do
+    let test :: forall r. (r ~ 'Nothing)
+             => Maybe (Either Int String)
+        test = fromType (Proxy @r)
+    test `shouldBe` Nothing
+
+
+specStructures :: Spec
+specStructures = describe "Maps and other structures" $ do
+  describe "[]" $ do
+    it "[]" $ do
+      let test :: forall r. (r ~ '[]) => [()]
+          test = fromType (Proxy @r)
+      test `shouldBe` []
+    it "[(Bool,Int)]" $ do
+      let test :: forall r. (r ~ '[ '( 'True,5), '( 'False,6)]) => [(Bool,Int)]
+          test = fromType (Proxy @r)
+      test `shouldBe` [(True,5),(False,6)]
+  describe "IntMap" $ do
+#if __GLASGOW_HASKELL__ >= 920
+    it "IntMap char, from '[ '(Nat,Char) ]" $ do
+      let test :: forall r. (r ~ '[ '(1,'H'), '(2,'e'), '(5,'o'), '(3,'b'), '(4,'l'), '(3,'l')]) => IM.IntMap Char
+          test = fromType (Proxy @r)
+      test `shouldBe` IM.fromList [(1,'H'),(2,'e'),(5,'o'),(4,'l'),(3,'l')]
+#endif
+    it "IntMap String, from NatMap" $ do
+      let test :: forall r. (r ~ Eval (FNM.FromList '[ '(1,"H"), '(4,"b"), '(2,"e"), '(5,"o"), '(4,"l"), '(3,"l")])) => IM.IntMap String
+          test = fromType (Proxy @r)
+      test `shouldBe` IM.fromList [(2,"e"),(1,"H"),(4,"l"),(3,"l"),(5,"o")]
+    it "IntMap String, with insert" $ do
+      let test :: forall r. (r ~ Eval (
+                    FNM.Insert 3 "hih" =<< FNM.FromList '[ '(1,"haa"), '(2,"hoo")]
+                  )) 
+              => IM.IntMap String
+          test = fromType (Proxy @r)
+      test 
+        `shouldBe` 
+        IM.fromList [ (3, "hih"), (1, "haa"), (2, "hoo")]
+  describe "Map" $ do
+#if __GLASGOW_HASKELL__ >= 920
+    it "Map Int char, from '[ '(Nat,Char) ]" $ do
+      let test :: forall r. (r ~ '[ '(1,'H'), '(2,'e'), '(5,'o'), '(4,'l'), '(3,'b'), '(3,'l')]) => DM.Map Int Char
+          test = fromType (Proxy @r)
+      test `shouldBe` DM.fromList [(1,'H'),(2,'e'),(5,'o'),(4,'l'),(3,'l')]
+#endif
+    it "Map Int String, from MapC" $ do
+      let test :: forall r. (r ~ Eval (FNMC.FromList '[ '(1,"H"), '(2,"e"), '(3,"c"), '(5,"o"), '(4,"l"), '(3,"l")])) => DM.Map Int String
+          test = fromType (Proxy @r)
+      test `shouldBe` DM.fromList [(2,"e"),(1,"H"),(4,"l"),(3,"l"),(5,"o")]
+    it "Map Int String, with insert" $ do
+      let test :: forall r. (r ~ Eval (
+                    FNMC.Insert 3 "hih" =<< FNMC.FromList '[ '(1,"haa"), '(2,"hoo")]
+                  )) 
+              => DM.Map Int String
+          test = fromType (Proxy @r)
+      test 
+        `shouldBe` 
+        DM.fromList [ (3, "hih"), (1, "haa"), (2, "hoo")]
+  describe "Set" $ do
+#if __GLASGOW_HASKELL__ >= 920
+    it "Set char, from '[Char]" $ do
+      let test :: forall r. (r ~ '[ 'H','e','o','l','l' ]) => DS.Set Char
+          test = fromType (Proxy @r)
+      test `shouldBe` DS.fromList ['H','e','o','l','l']
+#endif
+    it "Set String, from Set" $ do
+      let test :: forall r. (r ~ Eval (FS.FromList '["H","e","o","l","l"])) => DS.Set String
+          test = fromType (Proxy @r)
+      test `shouldBe` DS.fromList ["e","H","l","l","o"]
+    it "Set Int" $ do
+      let test :: forall r. (r ~ Eval (FS.FromList '[5, 9, 1, 8, 3, 5])) 
+              => DS.Set Int
+          test = fromType (Proxy @r)
+      test 
+        `shouldBe` 
+        DS.fromList [1, 3, 5, 8, 9]
+#if __GLASGOW_HASKELL__ >= 902
+  it "text" $ do
+    let test :: forall r. (r ~ 'FTxt.Text "trial") => DTxt.Text
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      DTxt.pack "trial"
+#endif
+
+type ExTr1 =
+    'FT.Node 1 
+       '[ 'FT.Node 2 
+          '[ 'FT.Node 3 '[ 'FT.Node 4 '[]]]
+        , 'FT.Node 5 '[ 'FT.Node 6 '[]]
+        ]
+
+type ExTr2 =
+    'FT.Node ('Just 1)
+        '[ 'FT.Node ('Just 2)
+            '[ 'FT.Node ('Just 3)
+                '[ 'FT.Node ('Just 4) '[]]
+             ]
+         , 'FT.Node ('Just 5)
+            '[ 'FT.Node ('Just 6) '[]
+             ]
+         ]
+
+type ExTr3 =
+    'FT.Node ('Just 1)
+        '[ 'FT.Node ('Just 2)
+            '[ 'FT.Node ('Just 3)
+                '[ 'FT.Node ('Just 4) '[]]
+             ]
+         , 'FT.Node ('Just 5)
+            '[ 'FT.Node 'Nothing '[]
+             ]
+         ]
+
+type ExTr4 =
+    'FT.Node ('Left 1)
+        '[ 'FT.Node ('Right "two")
+            '[ 'FT.Node ('Left 3)
+                '[ 'FT.Node ('Right "four") '[]]
+             ]
+         , 'FT.Node ('Left 5)
+            '[ 'FT.Node ('Right "six") '[]
+             ]
+         ]
+    
+specTrees :: Spec
+specTrees = describe "Tree structures" $ do
+  it "tree 1" $ do
+    let test :: forall r. (r ~ ExTr1) 
+             => DT.Tree Int
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      DT.Node 1 [DT.Node 2 [DT.Node 3 [DT.Node 4 []]], DT.Node 5 [DT.Node 6 []]]
+  it "tree 2" $ do
+    let test :: forall r. (r ~ ExTr2) 
+             => DT.Tree (Maybe Int)
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      DT.Node (Just 1) 
+        [ DT.Node (Just 2) 
+          [ DT.Node (Just 3) 
+            [ DT.Node (Just 4) []
+            ]
+          ]
+        , DT.Node (Just 5) 
+          [DT.Node (Just 6) []
+          ]
+        ]
+  it "tree 3" $ do
+    let test :: forall r. (r ~ ExTr3) 
+             => DT.Tree (Maybe Int)
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      DT.Node (Just 1) 
+        [ DT.Node (Just 2) 
+          [ DT.Node (Just 3) 
+            [ DT.Node (Just 4) []
+            ]
+          ]
+        , DT.Node (Just 5) 
+          [DT.Node Nothing []
+          ]
+        ]
+  it "tree 4" $ do
+    let test :: forall r. (r ~ ExTr4) 
+             => DT.Tree (Either Int String)
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      DT.Node (Left 1) 
+        [ DT.Node (Right "two") 
+          [ DT.Node (Left 3) 
+            [ DT.Node (Right "four") []
+            ]
+          ]
+        , DT.Node (Left 5) 
+          [DT.Node (Right "six") []
+          ]
+        ]
+
+specShowTypeable :: Spec
+specShowTypeable = describe "Show Type represented at the Kind level" $ do
+  it "Show Int" $ do
+    fromType @String (Proxy @Int)
+      `shouldBe`
+      "Int"
+  it "Show Set of Types" $ do
+    let test :: forall r. (r ~ Eval (FS.FromList '[Int, Maybe String, (), [Integer], IO ()])) 
+             => DS.Set String
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      DS.fromList ["Int", "Maybe [Char]", "()", "[Integer]", "IO ()"]
+
+specErrorMessage :: Spec
+specErrorMessage = describe "show GHC.TypeLits.ErrorMessage" $ do
+  it "text error" $ do
+    (fromType @DTxt.Text $ Proxy @('TL.Text "I am error"))
+      `shouldBe`
+      DTxt.pack "I am error"
+  it "ShowType 'True" $ do
+    (fromType @DTxt.Text $ Proxy @('TL.ShowType '()))
+      `shouldBe`
+      DTxt.pack "'()"
+  it "with Kinds" $ do
+    (fromType @DTxt.Text $ Proxy @('TL.Text "Kind: " 'TL.:<>: 'TL.ShowType 'True 'TL.:$$: 'TL.Text "Type: " 'TL.:<>: 'TL.ShowType Bool))
+      `shouldBe`
+      DTxt.pack "Kind: 'True\nType: Bool"
diff --git a/test/Test/Data/Set.hs b/test/Test/Data/Set.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Data/Set.hs
@@ -0,0 +1,221 @@
+{-# LANGUAGE CPP                    #-}
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE RankNTypes             #-}
+{-# LANGUAGE DataKinds              #-}
+{-# OPTIONS_GHC -Wall                       #-}
+{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
+
+module Test.Data.Set where
+
+import           Data.Proxy
+import           Data.Type.Equality ((:~:)(Refl))
+import           Test.Hspec (describe, it, shouldBe, Spec)
+import qualified Data.Set as DS
+
+import           Fcf (Eval, type (=<<), Map)
+import           Fcf.Data.Nat
+import           Fcf.Data.Set
+import           Fcf.Data.Reflect (fromType)
+import           Fcf.Alg.Sort
+
+--------------------------------------------------------------------------------
+
+-- > :kind! Eval (Size =<< FromList '[5, 3])
+-- Eval (Size =<< FromList '[5, 3]) :: TL.Natural
+-- = 2
+
+spec :: Spec
+spec = describe "Set" $ do
+  it "PowerSet" $ do
+    let test :: forall r. (r ~ Eval (PowerSet  =<< FromList '[1,2,9,5])) => DS.Set (DS.Set Int)
+        test = fromType (Proxy @r)
+    test 
+      `shouldBe` 
+      DS.powerSet (DS.fromList [1,2,9,5])
+  it "Size" $ do
+    let test :: forall r. (r ~ Eval (Size  =<< FromList '[5,3])) => Int
+        test = fromType (Proxy @r)
+    test `shouldBe` 2
+
+--------------------------------------------------------------------------------
+
+-- This module won't compile, if the Refl doesn't give the correct answer.
+--
+-- > :kind! (Eval Empty :: Set Nat)
+-- (Eval Empty :: Set Nat) :: Set TL.Natural
+-- = 'Set '[]
+_ = Refl :: (Eval Empty :: Set Nat)
+  :~: 'Set '[]
+
+
+-- This module won't compile, if the Refl doesn't give the correct answer.
+--
+-- > :kind! Eval (Singleton 1)
+-- Eval (Singleton 1) :: Set TL.Natural
+-- = 'Set '[1]
+_ = Refl :: Eval (Singleton 1)
+  :~: 'Set '[1]
+
+
+-- > :kind! Eval (Insert 3 =<< FromList '[1, 2])
+-- Eval (Insert 3 =<< FromList '[1, 2]) :: Set TL.Natural
+-- = 'Set '[3, 1, 2]
+_ = Refl :: Eval (Insert 3 =<< FromList '[1, 2])
+  :~: 'Set '[3, 1, 2]
+
+-- > :kind! Eval (Insert 2 =<< FromList '[1, 2])
+-- Eval (Insert 2 =<< FromList '[1, 2]) :: Set TL.Natural
+-- = 'Set '[1, 2]
+_ = Refl :: Eval (Insert 2 =<< FromList '[1, 2])
+  :~: 'Set '[1, 2]
+
+-- > :kind! Eval (Delete 5 =<< FromList '[5, 3])
+-- Eval (Delete 5 =<< FromList '[5, 3]) :: Set TL.Natural
+-- = 'Set '[3]
+_ = Refl :: Eval (Delete 5 =<< FromList '[5, 3])
+  :~: 'Set '[3]
+
+-- > :kind! Eval (Delete 7 =<< FromList '[5, 3])
+-- Eval (Delete 7 =<< FromList '[5, 3]) :: Set TL.Natural
+-- = 'Set '[5, 3]
+_ = Refl :: Eval (Delete 7 =<< FromList '[5, 3])
+  :~: 'Set '[5, 3]
+
+-- > :kind! Eval (Member 5 =<< FromList '[5, 3])
+-- Eval (Member 5 =<< FromList '[5, 3]) :: Bool
+-- = 'True
+_ = Refl :: Eval (Member 5 =<< FromList '[5, 3])
+  :~: 'True
+
+-- > :kind! Eval (Member 7 =<< FromList '[5, 3])
+-- Eval (Member 7 =<< FromList '[5, 3]) :: Bool
+-- = 'False
+_ = Refl :: Eval (Member 7 =<< FromList '[5, 3])
+  :~: 'False
+
+-- > :kind! Eval (NotMember 5 =<< FromList '[5, 3])
+-- Eval (NotMember 5 =<< FromList '[5, 3]) :: Bool
+-- = 'False
+_ = Refl :: Eval (NotMember 5 =<< FromList '[5, 3])
+  :~: 'False
+
+
+-- > :kind! Eval (NotMember 7 =<< FromList '[5, 3])
+-- Eval (NotMember 7 =<< FromList '[5, 3]) :: Bool
+-- = 'True
+_ = Refl :: Eval (NotMember 7 =<< FromList '[5, 3])
+  :~: 'True
+
+-- > :kind! Eval (Null =<< FromList '[5, 3])
+-- Eval (Null =<< FromList '[5, 3]) :: Bool
+-- = 'False
+_ = Refl :: Eval (Null =<< FromList '[5, 3])
+  :~: 'False
+
+-- > :kind! Eval (Null =<< Empty)
+-- Eval (Null =<< Empty) :: Bool
+-- = 'True
+_ = Refl :: Eval (Null =<< Empty)
+  :~: 'True
+
+-- > :kind! Eval (IsSubsetOf ('Set '[]) ('Set '[0,1,2,3,4]))
+-- Eval (IsSubsetOf ('Set '[]) ('Set '[0,1,2,3,4])) :: Bool
+-- = 'True
+_ = Refl :: Eval (IsSubsetOf ('Set '[]) ('Set '[0,1,2,3,4]))
+  :~: 'True
+
+-- > :kind! Eval (IsSubsetOf ('Set '[0,1]) ('Set '[0,1,2,3,4]))
+-- Eval (IsSubsetOf ('Set '[0,1]) ('Set '[0,1,2,3,4])) :: Bool
+-- = 'True
+_ = Refl :: Eval (IsSubsetOf ('Set '[0,1]) ('Set '[0,1,2,3,4]))
+  :~: 'True
+
+-- > :kind! Eval (IsSubsetOf ('Set '[0,2,1,3,4]) ('Set '[0,1,2,3,4]))
+-- Eval (IsSubsetOf ('Set '[0,2,1,3,4]) ('Set '[0,1,2,3,4])) :: Bool
+-- = 'True
+_ = Refl :: Eval (IsSubsetOf ('Set '[0,1,2,3,4]) ('Set '[0,1,2,3,4]))
+  :~: 'True
+
+-- > :kind! Eval (IsSubsetOf ('Set '[0,1,2,3,4,5]) ('Set '[0,1,2,3,4]))
+-- Eval (IsSubsetOf ('Set '[0,1,2,3,4,5]) ('Set '[0,1,2,3,4])) :: Bool
+-- = 'False
+_ = Refl :: Eval (IsSubsetOf ('Set '[0,1,2,3,4,5]) ('Set '[0,1,2,3,4]))
+  :~: 'False
+
+-- > :kind! Eval (IsProperSubsetOf ('Set '[0,1,2,3,4]) ('Set '[0,1,2,3,4]))
+-- Eval (IsProperSubsetOf ('Set '[0,1,2,3,4]) ('Set '[0,1,2,3,4])) :: Bool
+-- = 'False
+_ = Refl :: Eval (IsProperSubsetOf ('Set '[0,1,2,3,4]) ('Set '[0,1,2,3,4]))
+  :~: 'False
+
+-- > :kind! Eval (IsProperSubsetOf ('Set '[0,2,1,3]) ('Set '[0,1,2,3,4]))
+-- Eval (IsProperSubsetOf ('Set '[0,2,1,3]) ('Set '[0,1,2,3,4])) :: Bool
+-- = 'True
+_ = Refl :: Eval (IsProperSubsetOf ('Set '[0,2,1,3]) ('Set '[0,1,2,3,4]))
+  :~: 'True
+
+-- > :kind! Eval (Union (Eval (FromList '[5, 3])) (Eval (FromList '[5, 7])) )
+-- Eval (Union (Eval (FromList '[5, 3])) (Eval (FromList '[5, 7])) ) :: Set
+--                                                                        TL.Natural
+-- = 'Set '[7, 5, 3]
+_ = Refl ::  Eval (Union (Eval (FromList '[5, 3])) (Eval (FromList '[5, 7])) )
+  :~: 'Set '[7, 5, 3]
+
+-- > :kind! Eval (Difference (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7])))
+-- Eval (Difference (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7]))) :: Set
+--                                                                            TL.Natural
+-- = 'Set '[3]
+_ = Refl :: Eval (Difference (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7])))
+  :~: 'Set '[3]
+
+-- > :kind! Eval (Intersection (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7])))
+-- Eval (Intersection (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7]))) :: Set
+--                                                                              TL.Natural
+-- = 'Set '[5]
+_ = Refl :: Eval (Intersection (Eval (FromList '[3, 5])) (Eval (FromList '[5, 7]))) 
+  :~: 'Set '[5]
+
+-- > :kind! Eval (PowerSet =<< FromList '["a", "b", "c"])
+-- Eval (PowerSet =<< FromList '["a", "b", "c"]) :: Set
+--                                                    (Set TL.Symbol)
+-- = 'Set
+--     '[ 'Set '[], 'Set '["c"], 'Set '["b"], 'Set '["b", "c"],
+--        'Set '["a"], 'Set '["a", "b"], 'Set '["a", "c"],
+--        'Set '["a", "b", "c"]]
+--
+-- > :kind! Eval (PowerSet =<< FromList '[Int, Char, Maybe Int])
+-- Eval (PowerSet =<< FromList '[Int, Char, Maybe Int]) :: Set
+--                                                           (Set (*))
+-- = 'Set
+--     '[ 'Set '[], 'Set '[Maybe Int], 'Set '[Char],
+--        'Set '[Char, Maybe Int], 'Set '[Int], 'Set '[Int, Char],
+--        'Set '[Int, Maybe Int], 'Set '[Int, Char, Maybe Int]]
+_ = Refl :: Eval (PowerSet =<< FromList '[Int, Char, Maybe Int])
+  :~: 'Set
+    '[ 'Set '[], 'Set '[Maybe Int], 'Set '[Char],
+       'Set '[Char, Maybe Int], 'Set '[Int], 'Set '[Int, Char],
+       'Set '[Int, Maybe Int], 'Set '[Int, Char, Maybe Int]]
+
+-- > :kind! Eval (FromList '[1, 2])
+-- Eval (FromList '[1, 2]) :: Set TL.Natural
+-- = 'Set '[1, 2]
+_ = Refl :: Eval (FromList '[1, 2])
+  :~: 'Set '[1, 2]
+
+-- > :kind! Eval (ToList =<< PowerSet =<< FromList '[1,2,3])
+-- Eval (ToList =<< PowerSet =<< FromList '[1,2,3]) :: [Set
+--                                                        TL.Natural]
+-- = '[ 'Set '[], 'Set '[3], 'Set '[2], 'Set '[2, 3], 'Set '[1],
+--      'Set '[1, 2], 'Set '[1, 3], 'Set '[1, 2, 3]]
+_ = Refl :: Eval (ToList =<< PowerSet =<< FromList '[1,2,3])
+  :~: '[ 'Set '[], 'Set '[3], 'Set '[2], 'Set '[2, 3], 'Set '[1],
+         'Set '[1, 2], 'Set '[1, 3], 'Set '[1, 2, 3]]
+
+-- > :kind! Eval (Qsort NatListOrd =<< Map ToList =<< ToList =<< PowerSet =<< FromList '[1,2,3])
+-- Eval (Qsort NatListOrd =<< Map ToList =<< ToList =<< PowerSet =<< FromList '[1,2,3]) :: [[TL.Natural]]
+-- = '[ '[], '[1], '[1, 2], '[1, 2, 3], '[1, 3], '[2], '[2, 3], '[3]]
+_ = Refl :: Eval (Qsort NatListOrd =<< Map ToList =<< ToList =<< PowerSet =<< FromList '[1,2,3])
+  :~: '[ '[], '[1], '[1, 2], '[1, 2, 3], '[1, 3], '[2], '[2, 3], '[3]]
diff --git a/test/doctest.hs b/test/doctest.hs
--- a/test/doctest.hs
+++ b/test/doctest.hs
@@ -1,6 +1,9 @@
-import System.FilePath.Glob (glob)
+{-# LANGUAGE CPP                    #-}
+
 import Test.DocTest
 
+#if __GLASGOW_HASKELL__ >= 902
+
 exts :: [String]
 exts =
   [ "-XDataKinds"
@@ -11,6 +14,11 @@
   ]
 
 main :: IO ()
-main = do
-  xs <- glob "src/**/*.hs"
-  doctest (exts ++ xs)
+main = doctest $ exts ++ ["src"]
+
+#else
+
+main :: IO ()
+main = pure ()
+
+#endif
diff --git a/test/test.hs b/test/test.hs
--- a/test/test.hs
+++ b/test/test.hs
@@ -1,28 +1,33 @@
 {-# LANGUAGE
     DataKinds,
     KindSignatures,
+    TypeFamilies,
+    UndecidableInstances,
     TypeOperators #-}
 
 --------------------------------------------------------------------------------
 
 import           Data.Type.Equality ((:~:)(Refl))
-import           GHC.TypeLits (Nat)
-import           Fcf
+import           GHC.TypeLits (Nat, Symbol)
+import           Fcf hiding (type (<*>))
 
 --------------------------------------------------------------------------------
 
 import           Fcf.Data.Set
+import           Fcf.Control.Monad
+import           Fcf.Data.Tuple
+import           Fcf.Class.Monoid
+import           Fcf.Data.List
 
 --------------------------------------------------------------------------------
 
-
--- Compile-time tests
-
-_ = Refl :: Eval (ToList =<< PowerSet  =<< FromList '[1,2])
-        :~: '[ 'Set '[], 'Set '[2], 'Set '[1], 'Set '[1,2]]
-
--- Dummy
+import           Test.Alg as A (spec)
+import           Test.Data as D (spec)
+import           Test.Control as C (spec)
+import           Test.Hspec (hspec, parallel)
 
 main :: IO ()
-main = pure ()
-
+main = hspec $ parallel $ do
+  D.spec
+  C.spec
+  A.spec
