data-transform 0.1.0.2 → 0.1.1.0
raw patch · 2 files changed
+32/−18 lines, 2 filesdep ~base
Dependency ranges changed: base
Files
- data-transform.cabal +3/−4
- src/Data/Transform/Internal.hs +29/−14
data-transform.cabal view
@@ -1,5 +1,5 @@ name: data-transform-version: 0.1.0.2+version: 0.1.1.0 synopsis: Functions to transform data structures. description: This library provides a simple way to transform parts of complex data structures. It is based on Data.Data.@@ -22,14 +22,13 @@ MultiParamTypeClasses, FunctionalDependencies, UndecidableInstances- build-depends: base >= 4.9 && < 5,+ build-depends: base >= 4.14 && < 5, mtl, containers hs-source-dirs: src- ghc-options: -Wall -fwarn-tabs -fwarn-incomplete-record-updates -fwarn-monomorphism-restriction -fwarn-incomplete-uni-patterns+ ghc-options: -Wall -fwarn-incomplete-record-updates -fwarn-monomorphism-restriction -fwarn-incomplete-uni-patterns default-language: Haskell2010 source-repository head type: git location: git://github.com/ajscholl/data-transform.git-
src/Data/Transform/Internal.hs view
@@ -1,11 +1,11 @@-{-# LANGUAGE GADTs #-}-{-# LANGUAGE Trustworthy #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableInstances #-} ----------------------------------------------------------------------------- -- | -- Copyright : (c) 2014 Jonas Scholl@@ -132,8 +132,8 @@ -- | Same as 'appEndoList' but in a monadic context. appEndoListM :: (Monad m, Data a) => EndoListM m -> a -> m a-appEndoListM NilM a = return a-appEndoListM (ConsM f l) a = maybe (return a) (liftM unsafeCoerce . f) (cast a) >>= appEndoListM l+appEndoListM NilM a = pure a+appEndoListM (ConsM f l) a = maybe (pure a) (fmap unsafeCoerce . f) (cast a) >>= appEndoListM l -- | Class of transformations, i.e. objects containing endomorphisms. class Transformation d where@@ -211,7 +211,7 @@ -- | Same as 'transform' but with a monadic function. Calls 'fail' instead of -- 'error' if a type-error is detected.-transformM :: (MonadicTransformation d m, Data a) => d -> a -> m a+transformM :: (MonadicTransformation d m, Data a, MonadFail m) => d -> a -> m a transformM d a = case mkEndoListM d of f -> case getNeededTypeRepsM f `Set.difference` allContainedTypeReps a of s | not (Set.null s) -> fail $ "Data.DataTraverse.transformM: Could not find all needed types when mapping over a value of type " ++ show (typeOf a) ++ ". Types of missing terms: " ++ show (Set.toList s)@@ -271,7 +271,7 @@ -- >>> getSubtermsBy (<6) (3, 4.0, True, 'c', (False, (True, 5, 6))) -- [3, 5] getSubtermsBy :: (Data a, Data b) => (b -> Bool) -> a -> [b]-getSubtermsBy p = getSubtermsWith (\ x -> guard (p x) >> return [x])+getSubtermsBy p = getSubtermsWith (\ x -> guard (p x) >> pure [x]) -- | Returns all sub-terms (intermediate and non intermediate) of some type of a -- value which could be transformed to some 'Monoid'.@@ -280,11 +280,26 @@ -- -- Example: ----- >>> getSubtermsWith (\ x -> guard (x < 6) >> return [x]) (3, 4.0, True, 'c', (False, (True, 5, 6)))+-- >>> getSubtermsWith (\ x -> guard (x < 6) >> pure [x]) (3, 4.0, True, 'c', (False, (True, 5, 6))) -- [3, 5] getSubtermsWith :: (Data a, Data b, Monoid m) => (b -> Maybe m) -> a -> m-getSubtermsWith p = execWriter . transformM (\ x -> maybe (return ()) tell (p x) >> return x)+getSubtermsWith p = runErrorIdentity . execWriterT . transformM (\ x -> maybe (pure ()) tell (p x) >> pure x) +newtype ErrorIdentity a = ErrorIdentity { runErrorIdentity :: a }++instance Functor ErrorIdentity where+ fmap f (ErrorIdentity a) = ErrorIdentity (f a)++instance Applicative ErrorIdentity where+ pure = ErrorIdentity+ (ErrorIdentity f) <*> (ErrorIdentity a) = ErrorIdentity (f a)++instance Monad ErrorIdentity where+ (ErrorIdentity a) >>= f = f a++instance MonadFail ErrorIdentity where+ fail = error+ ------------------ -- * Type checking ------------------@@ -308,7 +323,7 @@ where helper :: Data a => a -> State (Set TypeRep) () helper x = do- let subterms = execWriter $ gmapM (\ y -> tell [WrappedData y] >> return y) x+ let subterms = execWriter $ gmapM (\ y -> tell [WrappedData y] >> pure y) x mapM_ (\ (WrappedData y) -> allContainedTypeReps' y) subterms -- | Construct a list of empty values, one for each constructor found in the data type.