diff --git a/Control/Monad/Ox.hs b/Control/Monad/Ox.hs
--- a/Control/Monad/Ox.hs
+++ b/Control/Monad/Ox.hs
@@ -18,9 +18,6 @@
 
 -- * Ox monad execution
 , execOx
-
--- * Utilities
-, memoize
 ) where
 
 import Control.Applicative ((<$>), (<*), (*>))
@@ -29,7 +26,6 @@
 import Control.Monad.Writer hiding (when)
 import Data.Maybe (maybeToList)
 import qualified Data.Vector as V
-import qualified Data.MemoCombinators as Memo
 
 -- | Observation type identifier.  It consists of a list of
 -- integers, each integer representing a state of the Ox
@@ -151,11 +147,6 @@
     x <- censor (map . first . setTop $ top) act
     setId (inc i)
     return x
-
--- | Memoize a function.  It can be useful when computing observation value
--- for a particular position is expensive and should be performed only once.
-memoize :: (Int -> a) -> Int -> a
-memoize f = Memo.integral f
 
 -- | Execute the Ox monad and retrieve the saved (with the 'save' and
 -- 'saves' functions) results.
diff --git a/Control/Monad/Ox/String.hs b/Control/Monad/Ox/String.hs
--- a/Control/Monad/Ox/String.hs
+++ b/Control/Monad/Ox/String.hs
@@ -56,6 +56,6 @@
         | otherwise      = 'x'
 
 -- | Pack the string, that is remove all adjacent repetitions,
--- for example /"aabcccdde" -> "abcde"/.
+-- for example /aabcccdde -> abcde/.
 pack :: String -> String
 pack = map head . L.group
diff --git a/Control/Monad/Ox/Text.hs b/Control/Monad/Ox/Text.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Ox/Text.hs
@@ -0,0 +1,58 @@
+-- | Popular transformation functions for the 'T.Text' observation type.
+
+module Control.Monad.Ox.Text
+( prefix
+, suffix
+, substr
+, shape
+, pack
+) where
+
+import qualified Data.Char as C
+import qualified Data.Text as T
+
+-- | Prefix of the given size or 'Nothing' if the size exceeds the
+-- length of the text.
+prefix :: Int -> T.Text -> Maybe T.Text
+prefix k xs
+    | k > 0  && k <= n      = Just $ T.take k xs
+    | k <= 0 && n + k > 0   = Just $ T.take (n + k) xs
+    | otherwise             = Nothing
+  where
+    n = T.length xs
+
+-- | Suffix of the given size or 'Nothing' if the size exceeds the
+-- length of the text.
+suffix :: Int -> T.Text -> Maybe T.Text
+suffix k xs
+    | k > 0  && k <= n      = Just . takeR k $ xs
+    | k <= 0 && n + k > 0   = Just . takeR (n + k) $ xs
+    | otherwise             = Nothing
+  where
+    takeR i = T.reverse . T.take i . T.reverse
+    n = T.length xs
+
+-- | All substrings of the given size.
+substr :: Int -> T.Text -> [T.Text]
+substr k xs
+    | T.length x < k = [] 
+    | otherwise = x : substr k (T.tail xs)
+  where
+    x = T.take k xs
+
+-- | Shape of the text.  All lower-case characters are mapped to 'l',
+-- upper-case characters to 'u', digits to 'd' and rest of characters
+-- to 'x'.
+shape :: T.Text -> T.Text
+shape = T.map translate
+  where
+    translate char
+        | C.isLower char = 'l'
+        | C.isUpper char = 'u'
+        | C.isDigit char = 'd'
+        | otherwise      = 'x'
+
+-- | Pack the text, that is remove all adjacent repetitions,
+-- for example /aabcccdde -> abcde/.
+pack :: T.Text -> T.Text
+pack = T.pack . map T.head . T.group
diff --git a/Control/Monad/Ox/Text/Lazy.hs b/Control/Monad/Ox/Text/Lazy.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Ox/Text/Lazy.hs
@@ -0,0 +1,65 @@
+-- | Popular transformation functions for the 'L.Text' observation type.
+
+module Control.Monad.Ox.Text.Lazy
+( prefix
+, suffix
+, substr
+, shape
+, pack
+) where
+
+import qualified Data.Char as C
+import qualified Data.Text.Lazy as L
+
+-- | Prefix of the given size or 'Nothing' if the size exceeds the
+-- length of the text.
+prefix :: Int -> L.Text -> Maybe L.Text
+prefix k xs
+    | k > 0  && k <= n      = Just $ takeL k xs
+    | k <= 0 && n + k > 0   = Just $ takeL (n + k) xs
+    | otherwise             = Nothing
+  where
+    n = lengthL xs
+
+-- | Suffix of the given size or 'Nothing' if the size exceeds the
+-- length of the text.
+suffix :: Int -> L.Text -> Maybe L.Text
+suffix k xs
+    | k > 0  && k <= n      = Just . takeR k $ xs
+    | k <= 0 && n + k > 0   = Just . takeR (n + k) $ xs
+    | otherwise             = Nothing
+  where
+    takeR i = L.reverse . takeL i . L.reverse
+    n = lengthL xs
+
+-- | All substrings of the given size.
+substr :: Int -> L.Text -> [L.Text]
+substr k xs
+    | lengthL x < k = [] 
+    | otherwise = x : substr k (L.tail xs)
+  where
+    x = takeL k xs
+
+-- | Shape of the text.  All lower-case characters are mapped to 'l',
+-- upper-case characters to 'u', digits to 'd' and rest of characters
+-- to 'x'.
+shape :: L.Text -> L.Text
+shape = L.map translate
+  where
+    translate char
+        | C.isLower char = 'l'
+        | C.isUpper char = 'u'
+        | C.isDigit char = 'd'
+        | otherwise      = 'x'
+
+-- | Pack the text, that is remove all adjacent repetitions,
+-- for example /aabcccdde -> abcde/.
+pack :: L.Text -> L.Text
+pack = L.pack . map L.head . L.group
+
+-- | Length of the lazy text as plain Int.
+lengthL :: L.Text -> Int
+lengthL = fromIntegral . L.length
+
+takeL :: Int -> L.Text -> L.Text
+takeL = L.take . fromIntegral
diff --git a/monad-ox.cabal b/monad-ox.cabal
--- a/monad-ox.cabal
+++ b/monad-ox.cabal
@@ -1,5 +1,5 @@
 name:               monad-ox
-version:            0.1.1
+version:            0.2.0
 synopsis:           Monad for observation extraction
 description:
     The library provides an Ox monad and accompanying functions which
@@ -20,15 +20,17 @@
 
 library
     build-depends:
-        base >= 4 && <= 4.5
+        base >= 4 && < 5
       , containers
       , vector
-      , data-memocombinators >= 0.4.3 && < 0.4.4
+      , text
       , mtl >= 2
 
     exposed-modules:
         Control.Monad.Ox
-        Control.Monad.Ox.String
+      , Control.Monad.Ox.String
+      , Control.Monad.Ox.Text
+      , Control.Monad.Ox.Text.Lazy
 
     ghc-options: -Wall
 
