packages feed

monad-ox (empty) → 0.1.0

raw patch · 5 files changed

+293/−0 lines, 5 filesdep +basedep +containersdep +data-memocombinatorssetup-changed

Dependencies added: base, containers, data-memocombinators, mtl, vector

Files

+ Control/Monad/Ox.hs view
@@ -0,0 +1,165 @@+-- | The Ox monad facilitates writing functional expressions over the+-- input sentence with arbitrary type of sentence token.++module Control.Monad.Ox+( +-- * Types+  Ox+, Id++-- * Functions+, atWith+, atsWith+, save+, saves+, when+, whenJT+, group++-- * Ox monad execution+, execOx++-- * Utilities+, memoize+) where++import Control.Applicative ((<$>), (<*), (*>))+import Control.Arrow (first)+import Control.Monad.State hiding (when)+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+-- monad on the particular level.+type Id = [Int]++-- | Increment the integer component of the top-most level.+inc :: Id -> Id+inc []      = error "incId: null id"+inc (x:xs)  = x+1 : xs++-- | Push new value to the Id stack.+grow :: Id -> Id+grow xs = 1 : xs++-- | Pop value from the stack.+shrink :: Id -> Id+shrink []       = error "shrink: null id"+shrink (_:xs)   = xs++-- | Set the top-most component to the given value.+getTop :: Id -> Int+getTop [] = error "getTop: null id"+getTop (x:_) = x++-- | Set the top-most component to the given value.+setTop :: Int -> Id -> Id+setTop _ [] = error "setTop: null id"+setTop x (_:xs) = x:xs++-- | The Ox is a monad stack with observation type identifier handled by+-- the state monad and the resulting observation values paired with identifiers+-- printed using the writer monad.+type Ox t w a = WriterT [(Id, w)] (State Id) a++-- | Retrieve the current identifier value.+getId :: Ox t w Id+getId = lift get+{-# INLINE getId #-}++-- | Set the new identifier value.+setId :: Id -> Ox t w ()+setId = lift . put+{-# INLINE setId #-}++-- | Update the current identifier of the Ox monad.+updateId :: (Id -> Id) -> Ox t w ()+updateId f = do+    i <- getId+    setId (f i)++-- | Increase the current identifier of the Ox monad.+incId :: Ox t w ()+incId = updateId inc++-- | Perform the identifier-dependent action and increase the identifier.+withId :: (Id -> Ox t w a) -> Ox t w a+withId act = do+    x <- act =<< getId+    incId+    return x++-- | Perform the Ox action on the lower level.+below :: Ox t w a -> Ox t w a+below act = updateId grow *> act <* updateId shrink++-- | Value of the 't -> a' function with respect to the given sentence+-- and sentence position.  Return Nothing if the position is out of+-- bounds.+atWith :: V.Vector t -> (t -> a) -> Int -> Maybe a+atWith xs f k =+    if k < 0 || k >= V.length xs+        then Nothing+        else Just $ f (xs V.! k)++-- | Value of the 't -> [a]' function with respect to the given sentence+-- and sentence position.  Return empty list if the position is out of+-- bounds.+atsWith  :: V.Vector t -> (t -> [a]) -> Int -> [a]+atsWith xs f k =+    if k < 0 || k >= V.length xs+        then []+        else f (xs V.! k)++-- | Save observation values in the writer monad of the Ox stack.+saves :: [w] -> Ox t w ()+saves xs = withId $ \i -> tell [(i, x) | x <- xs]++-- | Save the observation value.+save :: Maybe w -> Ox t w ()+save = saves . maybeToList++-- | Perform the Ox action only when the 'cond' is True.  It works like+-- the standard 'Control.Monad.when' function but also changes the current+-- identifier value.+when :: Bool -> Ox t w a -> Ox t w (Maybe a)+when cond act = do+    x <- case cond of+        False -> return Nothing+        True  -> Just <$> below act+    incId+    return x++-- | Perform the action only when the given condition is equal to Just True.+whenJT :: Maybe Bool -> Ox t w a -> Ox t w (Maybe a)+whenJT cond =+    when (justTrue cond)+  where+    justTrue Nothing  = False+    justTrue (Just x) = x++-- | Make all embedded observations to be indistinguishable with respect+-- to their top-most identifier components.+-- TODO: Perhaps should set only the current level, not the deeper ones.+group :: Ox t w a -> Ox t w a+group act = do +    i <- getId+    let top = getTop i+    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.+execOx :: Ox t w a -> [(Id, w)]+execOx ox =+    (map (first reverse) . fst)+    (runState (execWriterT ox) [1])
+ Control/Monad/Ox/String.hs view
@@ -0,0 +1,61 @@+-- | Popular transformation functions for the 'String' observation type.++module Control.Monad.Ox.String+( prefix+, suffix+, substr+, shape+, pack+) where++import qualified Data.Char as C+import qualified Data.List as L++-- | Prefix of the given size or 'Nothing' if the size exceeds the+-- length of the string.+prefix :: Int -> String -> Maybe String+prefix k xs+    | k > 0  && k <= n      = Just $ take k xs+    | k <= 0 && n + k > 0   = Just $ take (n + k) xs+    | otherwise             = Nothing+  where+    n = length xs++-- | Suffix of the given size or 'Nothing' if the size exceeds the+-- length of the string.+suffix :: Int -> String -> Maybe String+suffix k xs+    | k > 0  && k <= n      = Just . reverse . take k . reverse $ xs+    | k <= 0 && n + k > 0   = Just . reverse . take (n + k) . reverse $ xs+    | otherwise             = Nothing+  where+    n = length xs++-- | All substrings of the given size.+substr :: Int -> String -> [String]+substr k xs+    | k > 0 && k <= n   = relevant $ map (take k) (L.tails xs)+    | otherwise         = []+  where+    n = length xs+    relevant+        = reverse+        . dropWhile ((<k).length)+        . reverse++-- | Shape of the string.  All lower-case characters are mapped to 'l',+-- upper-case characters to 'u', digits to 'd' and rest of characters+-- to 'x'.+shape :: String -> String+shape = map translate+  where+    translate char+        | C.isLower char = 'l'+        | C.isUpper char = 'u'+        | C.isDigit char = 'd'+        | otherwise      = 'x'++-- | Pack the string, that is remove all adjacent repetitions,+-- for example /"aabcccdde" -> "abcde"/.+pack :: String -> String+pack = map head . L.group
+ LICENSE view
@@ -0,0 +1,26 @@+Copyright (c) 2012, IPI PAN+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.++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.
+ Setup.lhs view
@@ -0,0 +1,4 @@+#! /usr/bin/env runhaskell++> import Distribution.Simple+> main = defaultMain
+ monad-ox.cabal view
@@ -0,0 +1,37 @@+name:               monad-ox+version:            0.1.0+synopsis:           Monad for observation extraction+description:+    The library provides an Ox monad and accompanying functions which+    are intended to simplify writing functional expressions over input+    sentence with arbitrary type of token.  Values of such functional+    expressions can be subsequently used as observations in input data+    for sequential classifiers.+license:            BSD3+license-file:       LICENSE+cabal-version:      >= 1.6+copyright:          Copyright (c) 2012 IPI PAN+author:             Jakub Waszczuk+maintainer:         waszczuk.kuba@gmail.com+stability:          experimental+category:           Control, Natural Language Processing+homepage:           https://github.com/kawu/monad-ox+build-type:         Simple++library+    build-depends:+        base >= 4 && < 5+      , containers+      , vector+      , data-memocombinators >= 0.4.3 && < 0.4.4+      , mtl >= 2++    exposed-modules:+        Control.Monad.Ox+        Control.Monad.Ox.String++    ghc-options: -Wall++source-repository head+    type: git+    location: git://github.com/kawu/monad-ox.git