diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,4 @@
+0.4.4
+===
+
+- Added some common patterns
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2013, Tony Day
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Tony Day nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/mealy.cabal b/mealy.cabal
--- a/mealy.cabal
+++ b/mealy.cabal
@@ -1,117 +1,119 @@
 cabal-version: 3.0
-name:          mealy
-version:       0.4.3
-license:       BSD-3-Clause
-copyright:     Tony Day (c) 2013 - 2022
-maintainer:    tonyday567@gmail.com
-author:        Tony Day
-homepage:      https://github.com/tonyday567/mealy#readme
-bug-reports:   https://github.com/tonyday567/mealy/issues
-synopsis:      Mealy machines for processing time-series and ordered data.
+name: mealy
+version: 0.4.4
+license: BSD-3-Clause
+license-file: LICENSE
+copyright: Tony Day (c) 2013
+category: algorithm
+author: Tony Day
+maintainer: tonyday567@gmail.com
+homepage: https://github.com/tonyday567/mealy#readme
+bug-reports: https://github.com/tonyday567/mealy/issues
+synopsis: Mealy machines for processing time-series and ordered data.
 description:
-  @mealy@ provides support for computing statistics (such as an average or a standard deviation)
-  as current state. Usage is to supply a decay function representing the relative weights of recent values versus older ones, in the manner of exponentially-weighted averages. The library attempts to be polymorphic in the statistic which can be combined in applicative style.
+    @mealy@ provides support for computing statistics (such as an average or a standard deviation) as current state. Usage is to supply a decay function representing the relative weights of recent values versus older ones, in the manner of exponentially-weighted averages. The library attempts to be polymorphic in the statistic which can be combined in applicative style.
 
-  == Usage
+    == Usage
 
-  >>> import Mealy
+    >>> import Mealy
 
-  >>> fold ((,) <$> ma 0.9 <*> std 0.9) [1..100]
-  (91.00265621044142,9.472822805289121)
+    >>> fold ((,) <$> ma 0.9 <*> std 0.9) [1..100]
+    (91.00265621044142,9.472822805289121)
 
-category:      folding
-build-type:    Simple
-tested-with:   GHC == 8.10.7 || ==9.2.8 || ==9.4.5 || ==9.6.2
+build-type: Simple
+tested-with: GHC == 8.10.7 || ==9.2.8 || ==9.4.5 || ==9.6.2
+extra-doc-files:
+    ChangeLog.md
+    readme.org
 
 source-repository head
-  type:     git
-  location: https://github.com/tonyday567/mealy
+    type: git
+    location: https://github.com/tonyday567/mealy
 
+common ghc-options-stanza
+    ghc-options:
+        -Wall
+        -Wcompat
+        -Widentities
+        -Wincomplete-record-updates
+        -Wincomplete-uni-patterns
+        -Wpartial-fields
+        -Wredundant-constraints
+
 common ghc2021-stanza
-  if impl(ghc >=9.2)
-    default-language:
-      GHC2021
-  if impl(ghc <9.2)
-    default-language:
-      Haskell2010
-    default-extensions:
-      BangPatterns
-      BinaryLiterals
-      ConstrainedClassMethods
-      ConstraintKinds
-      DeriveDataTypeable
-      DeriveFoldable
-      DeriveFunctor
-      DeriveGeneric
-      DeriveLift
-      DeriveTraversable
-      DoAndIfThenElse
-      EmptyCase
-      EmptyDataDecls
-      EmptyDataDeriving
-      ExistentialQuantification
-      ExplicitForAll
-      FlexibleContexts
-      FlexibleInstances
-      ForeignFunctionInterface
-      GADTSyntax
-      GeneralisedNewtypeDeriving
-      HexFloatLiterals
-      ImplicitPrelude
-      InstanceSigs
-      KindSignatures
-      MonomorphismRestriction
-      MultiParamTypeClasses
-      NamedFieldPuns
-      NamedWildCards
-      NumericUnderscores
-      PatternGuards
-      PolyKinds
-      PostfixOperators
-      RankNTypes
-      RelaxedPolyRec
-      ScopedTypeVariables
-      StandaloneDeriving
-      StarIsType
-      TraditionalRecordSyntax
-      TupleSections
-      TypeApplications
-      TypeOperators
-      TypeSynonymInstances
-  if impl(ghc <9.2) && impl(ghc >=8.10)
-    default-extensions:
-      ImportQualifiedPost
-      StandaloneKindSignatures
+    if impl ( ghc >= 9.2 )
+        default-language: GHC2021
 
-common ghc-options-stanza
-  ghc-options:
-    -Wall
-    -Wcompat
-    -Wincomplete-record-updates
-    -Wincomplete-uni-patterns
-    -Wredundant-constraints
-    -Widentities
-    -Wpartial-fields
+    if impl ( ghc < 9.2 )
+        default-language: Haskell2010
+        default-extensions:
+            BangPatterns
+            BinaryLiterals
+            ConstrainedClassMethods
+            ConstraintKinds
+            DeriveDataTypeable
+            DeriveFoldable
+            DeriveFunctor
+            DeriveGeneric
+            DeriveLift
+            DeriveTraversable
+            DoAndIfThenElse
+            EmptyCase
+            EmptyDataDecls
+            EmptyDataDeriving
+            ExistentialQuantification
+            ExplicitForAll
+            FlexibleContexts
+            FlexibleInstances
+            ForeignFunctionInterface
+            GADTSyntax
+            GeneralisedNewtypeDeriving
+            HexFloatLiterals
+            ImplicitPrelude
+            InstanceSigs
+            KindSignatures
+            MonomorphismRestriction
+            MultiParamTypeClasses
+            NamedFieldPuns
+            NamedWildCards
+            NumericUnderscores
+            PatternGuards
+            PolyKinds
+            PostfixOperators
+            RankNTypes
+            RelaxedPolyRec
+            ScopedTypeVariables
+            StandaloneDeriving
+            StarIsType
+            TraditionalRecordSyntax
+            TupleSections
+            TypeApplications
+            TypeOperators
+            TypeSynonymInstances
 
-library
-  import: ghc2021-stanza
-  import: ghc-options-stanza
-  exposed-modules:
-    Data.Mealy
-    Data.Mealy.Quantiles
-    Data.Mealy.Simulate
+    if impl ( ghc < 9.2 ) && impl ( ghc >= 8.10 )
+        default-extensions:
+            ImportQualifiedPost
+            StandaloneKindSignatures
 
-  hs-source-dirs:   src
-  build-depends:
-    , adjunctions        ^>=4.4
-    , base               >=4.12   && <5
-    , containers         ^>=0.6.2
-    , mwc-probability    ^>=2.3.1
-    , numhask            >=0.10 && <0.12
-    , numhask-array      >=0.10.1 && <0.12
-    , primitive          >=0.7.2   && <0.9
-    , profunctors        ^>=5.6.2
-    , tdigest            >=0.2.1 && <4
-    , text               >=1.2.4   && <2.1
-    , vector             >=0.12.3  && <0.14
-    , vector-algorithms  >=0.8.0   && <0.10
+library
+    import: ghc-options-stanza
+    import: ghc2021-stanza
+    hs-source-dirs: src
+    build-depends:
+        , adjunctions       >=4.0 && <5
+        , base              >=4.7 && <5
+        , containers        >=0.6 && <0.7
+        , mwc-probability   ^>=2.3.1
+        , numhask           >=0.10 && <0.12
+        , numhask-array     >=0.10 && <0.12
+        , primitive         >=0.7.2 && <0.9
+        , profunctors       >=5.6.2 && <5.7
+        , tdigest           >=0.2.1 && <0.4
+        , text              >=1.2 && <2.1
+        , vector            >=0.12.3 && <0.14
+        , vector-algorithms >=0.8.0 && <0.10
+    exposed-modules:
+        Data.Mealy
+        Data.Mealy.Quantiles
+        Data.Mealy.Simulate
diff --git a/readme.org b/readme.org
new file mode 100644
--- /dev/null
+++ b/readme.org
@@ -0,0 +1,36 @@
+#+TITLE: mealy
+
+[[https://hackage.haskell.org/package/mealy][file:https://img.shields.io/hackage/v/mealy.svg]] [[https://github.com/tonyday567/mealy/actions?query=workflow%3Ahaskell-ci][file:https://github.com/tonyday567/mealy/workflows/haskell-ci/badge.svg]]
+
+A 'Mealy' is a triple of functions
+
+- (a -> b) *inject*: Convert (initial) input into the (initial) state type.
+- (b -> a -> b) *step*: Update state given prior state and (new) input.
+- (c -> b) *extract*: Convert state to the output type.
+
+A sum, for example, looks like ~M id (+) id~ where the first id is the initial injection and the second id is the covariant extraction.
+
+This library provides support for computing statistics (such as an average or a standard deviation)
+as current state within a mealy context.
+
+* Usage
+
+Usage is to supply a decay function representing the relative weights of recent values versus older ones, in the manner of exponentially-weighted averages. The library attempts to be polymorphic in the statistic which can be combined in applicative style.
+
+#+begin_src haskell :results output
+:set prompt "> "
+import Prelude
+import Data.Mealy
+#+end_src
+
+#+begin_src haskell :results output
+fold ((,) <$> ma 0.9 <*> std 0.9) [1..100::Double]
+#+end_src
+
+#+RESULTS:
+: (91.00265621044142,9.472822805289121)
+
+
+* Reference
+
+[[https://stackoverflow.com/questions/27997155/finite-state-transducers-in-haskell][Finite State Transducers]]
diff --git a/src/Data/Mealy.hs b/src/Data/Mealy.hs
--- a/src/Data/Mealy.hs
+++ b/src/Data/Mealy.hs
@@ -40,6 +40,12 @@
     delay1,
     delay,
     window,
+    diff,
+    gdiff,
+    same,
+    countM,
+    sumM,
+    listify,
 
     -- * median
     Medianer (..),
@@ -53,6 +59,7 @@
 import Data.Bifunctor
 import Data.Functor.Rep
 import Data.List (scanl')
+import Data.Map qualified as Map
 import Data.Profunctor
 import Data.Sequence (Seq)
 import Data.Sequence qualified as Seq
@@ -60,7 +67,7 @@
 import Data.Typeable (Typeable)
 import GHC.TypeLits
 import NumHask.Array as F
-import NumHask.Prelude hiding (L1, asum, fold, id, last, (.))
+import NumHask.Prelude hiding (asum, diff, fold, id, last, (.))
 
 -- $setup
 --
@@ -94,11 +101,11 @@
 
 instance Exception MealyError
 
--- | A 'Mealy' is a triple of functions
+-- | A 'Mealy' a b is a triple of functions
 --
--- * (a -> b) __inject__ Convert an input into the state type.
--- * (b -> a -> b) __step__ Update state given prior state and (new) input.
--- * (c -> b) __extract__ Convert state to the output type.
+-- * (a -> s) __inject__ Convert an input into the state type.
+-- * (s -> a -> s) __step__ Update state given prior state and (new) input.
+-- * (s -> b) __extract__ Convert state to the output type.
 --
 -- By adopting this order, a Mealy sum looks like:
 --
@@ -106,7 +113,7 @@
 --
 -- where the first id is the initial injection to a contravariant position, and the second id is the covariant extraction.
 --
--- __inject__ kicks off state on the initial element of the Foldable, but is otherwise be independent of __step__.
+-- __inject__ kicks off state on the initial element of the Foldable, but is otherwise  independent of __step__.
 --
 -- > scan (M i s e) (x : xs) = e <$> scanl' s (i x) xs
 data Mealy a b = forall c. Mealy (a -> c) (c -> a -> c) (c -> b)
@@ -492,6 +499,34 @@
 window :: Int -> Mealy a (Seq.Seq a)
 window n = M Seq.singleton (\xs x -> Seq.take n (x Seq.<| xs)) id
 {-# INLINEABLE window #-}
+
+-- | binomial operator applied to last and this value
+diff :: (a -> a -> b) -> Mealy a b
+diff f = f <$> id <*> delay1 undefined
+
+-- | generalised diff function.
+gdiff :: (a -> b) -> (a -> a -> b) -> Mealy a b
+gdiff d0 d = M (\a -> (d0 a, a)) (\(_, a') a -> (d a a', a)) fst
+
+-- | Unchanged since last time.
+same :: (Eq b) => (a -> b) -> Mealy a Bool
+same b = M (\a -> (True, b a)) (\(s, x) a -> (s && b a == x, x)) fst
+
+-- | Count observed values
+countM :: (Ord a) => Mealy a (Map.Map a Int)
+countM = M (`Map.singleton` 1) (\m k -> Map.insertWith (+) k 1 m) id
+
+-- | Sum values of a key-value pair.
+sumM :: (Ord a, Additive b) => Mealy (a, b) (Map.Map a b)
+sumM = M (uncurry Map.singleton) (\m (k, v) -> Map.insertWith (+) k v m) id
+
+-- | Convert a Mealy to a Mealy operating on lists.
+listify :: Mealy a b -> Mealy [a] [b]
+listify (M sExtract sStep sInject) = M extract step inject
+  where
+    extract = fmap sExtract
+    step = zipWith sStep
+    inject = fmap sInject
 
 -- | A rough Median.
 -- The average absolute value of the stat is used to callibrate estimate drift towards the median
diff --git a/src/Data/Mealy/Quantiles.hs b/src/Data/Mealy/Quantiles.hs
--- a/src/Data/Mealy/Quantiles.hs
+++ b/src/Data/Mealy/Quantiles.hs
@@ -6,6 +6,7 @@
   ( median,
     quantiles,
     digitize,
+    signalize,
   )
 where
 
@@ -88,7 +89,7 @@
         VU.unsafeFreeze v
 
 -- | A mealy that computes the running quantile bucket. For example,
--- in a scan, @digitize 0.9 [0,0.5,1]@ returns:
+-- in a scan, @digitize 0.9 [0.5]@ returns:
 --
 -- * 0 if the current value is less than the current mealy median.
 --
@@ -110,3 +111,8 @@
                   else 1
             )
               <$> xs
+
+-- | transform an input to a [0,1] signal, via digitalization.
+signalize :: Double -> [Double] -> Mealy Double Double
+signalize r qs' =
+  (\x -> fromIntegral x / fromIntegral (length qs' + 1)) <$> digitize r qs'
