{-# OPTIONS -Wall #-} -------------------------------------------------------------------------------- -- | -- Module : Precis.Utils.Common -- Copyright : (c) Stephen Tetley 2010 -- License : BSD3 -- -- Maintainer : Stephen Tetley -- Stability : highly unstable -- Portability : to be determined. -- -- Utils -- -------------------------------------------------------------------------------- module Precis.Utils.Common ( -- * Hughes list H , emptyH , wrapH , consH , snocH , appendH , veloH , concatH , toListH , fromListH -- * Others , unlist , mapLeft , mapRight , onSuccessM , pstar , pstar2 , star , star2 ) where import Control.Monad -- Hughes lists type H a = [a] -> [a] infixr 2 `snocH` emptyH :: H a emptyH = id wrapH :: a -> H a wrapH a = consH a id consH :: a -> H a -> H a consH a f = (a:) . f snocH :: H a -> a -> H a snocH f a = f . (a:) appendH :: H a -> H a -> H a appendH f g = f . g -- | Traverse a list as per 'map' applying the supplied function -- to each element, *but* pruduce a Hughes list as output. -- -- -- veloH :: (a -> b) -> [a] -> H b veloH _ [] = id veloH f (x:xs) = consH (f x) $ veloH f xs concatH :: [H a] -> H a concatH = foldr (.) id toListH :: H a -> [a] toListH = ($ []) fromListH :: [a] -> H a fromListH [] = id fromListH xs = (xs++) -------------------------------------------------------------------------------- unlist :: [String] -> String unlist [] = "" unlist [w] = w unlist (w:ws) = w ++ ',' : ' ' : unwords ws -- Where\'s the bifunctor class when you need it... mapLeft :: (a -> s) -> Either a b -> Either s b mapLeft f (Left a) = Left $ f a mapLeft _ (Right b) = Right b mapRight :: (b -> t) -> Either a b -> Either a t mapRight _ (Left a) = Left a mapRight f (Right b) = Right $ f b onSuccessM :: Monad m => m (Either a b) -> (b -> m c) -> m (Either a c) onSuccessM ma msk = ma >>= step where step (Left a) = return (Left a) step (Right b) = liftM Right $ msk b -------------------------------------------------------------------------------- -- pstars - starling combinator with args permuted -- useful for record updates pstar :: (a -> r -> ans) -> (r -> a) -> r -> ans pstar f fa x = f (fa x) x pstar2 :: (a -> b -> r -> ans) -> (r -> a) -> (r -> b) -> r -> ans pstar2 f fa fb x = f (fa x) (fb x) x star :: (r -> a) -> (a -> r -> ans) -> r -> ans star fa f x = f (fa x) x star2 :: (r -> a) -> (r -> b) -> (a -> b -> r -> ans) -> r -> ans star2 fa fb f x = f (fa x) (fb x) x