packages feed

morfette-0.2: GramLab/Utils.hs

module GramLab.Utils ( join
                     , splitOn
                     , splitWith
                     , splitInto
                     , padLeft
                     , padRight
                     , makeList 
                     , lowercase
                     , uppercase
                     , at
                     , distribute
                     , distributeOver
                     , cumulDifference
                     , index
                     , unfoldrM
                     , tokenize
                     , uniq
                     )
    
where
import Data.List
import Data.Char
import qualified Data.Map as Map
import Data.Set(Set)
import qualified Data.Set as Set
import qualified Data.Traversable as T
import qualified Control.Monad.State as S
import Control.Monad (liftM)
import Debug.Trace
-- Lists/Strings
join        :: [a] -> [[a]] -> [a]
join sep xs = concat $ intersperse sep xs

splitOn :: (Eq a) => a -> [a] -> [[a]]
splitOn = splitWith . (==)

splitWith ::  (a -> Bool) -> [a] -> [[a]]
splitWith f s =  case dropWhile f s of
                   [] -> []
                   s' -> w : splitWith f s''
                       where (w, s'') = break f s'

splitInto :: Int -> [a] -> [[a]]
splitInto size [] = []
splitInto size xs = let (ws,ys) = splitAt size xs
                    in  ws:splitInto size ys

padLeft              :: a -> Int -> [a] -> [a]
padLeft  pad size xs = reverse $ padRight pad size $ reverse xs

padRight             :: a -> Int -> [a] -> [a]
padRight pad size xs = take size (xs ++ (repeat pad))

lowercase :: String -> String
--lowercase xs | trace xs False = undefined
lowercase xs = map toLower xs

uppercase :: String -> String
uppercase  = map toUpper 

makeList size elt = take size (repeat elt)

at err  m k = case Map.lookup k m of
           Nothing -> error (err k)
           Just x  -> x

distributeOver   :: Int -> [t] -> [[t]]
distributeOver i = distribute ([],(replicate i []))

distribute (xs,ys)   []     = xs ++ ys
distribute (xs,[])   zs     = distribute ([],xs) zs
distribute (xs,y:ys) (z:zs) = distribute ((z:y):xs,ys) zs

cumulDifference :: (Ord a) => [Set a] -> [Set a]
cumulDifference = snd . mapAccumL (\z x -> (z `Set.union` x, x `Set.difference` z)) Set.empty 

index xs = S.evalState (T.mapM count xs) 0
    where count a = do
            i <- S.get
            S.put (i+1)
            return (i,a)
unfoldrM f b  = do 
  result <- f b
  case result of
    Just (a,new_b) -> liftM (a:) (unfoldrM f new_b)
    Nothing        -> return []

sepPunct :: String -> [String]
sepPunct xs = let (before,rest) = span isPunctuation xs
                  (after,this)  = span isPunctuation (reverse rest)
              in filter (not . null) [before,reverse this,reverse after]
tokenize :: String -> [String]
tokenize = concatMap sepPunct . words


uniq :: (Ord a) => [a] -> [a]
{-# SPECIALIZE INLINE uniq :: [String] -> [String] #-}
uniq = Set.toList . Set.fromList