-- | -- Module : Data.IntermediateStructures1 -- Copyright : (c) Oleksandr Zhabenko 2019-2024 -- License : MIT -- Maintainer : oleksandr.zhabenko@yahoo.com -- -- Some simple functions to deal with transformations from structures to other ones, basically lists. -- -- The function 'mapI' is taken from the [mmsyn5](https://hackage.haskell.org/package/mmsyn5) package. This inspired some more general functionality. {-# LANGUAGE NoImplicitPrelude, BangPatterns #-} {-# OPTIONS_HADDOCK -show-extensions #-} module Data.IntermediateStructures1 ( -- * Operations to apply a function or two different functions to an element of the outer list (some of them create inner list) mapI , map2I -- * Generalized construction functions for some other ones (generative functions) , inter , inter' , swapinter , swapinter' ) where import GHC.Base import GHC.List (concatMap) -- | Function that applies additional function @f :: a -> [a]@ to @a@ if @p :: a -> Bool@ and @p a = True@ mapI :: (a -> Bool) -> (a -> [a]) -> [a] -> [a] mapI p f = concatMap (\x -> if p x then f x else [x]) {-# INLINE mapI #-} -- | Function that applies additional function @f :: a -> [[a]]@ to @a@ if @p :: a -> Bool@ and @p a = True@ map2I :: (a -> Bool) -> (a -> [[a]]) -> [a] -> [a] map2I p f = mconcat . concatMap (\x -> if p x then f x else [[x]]) {-# INLINE map2I #-} -- | Some general transformation where the arguments that are not present are calculated from the one data argument @a@ being just present. Can be used to contstruct function @a -> d@ from some additional ideas. inter :: (a -> b) -> (a -> c) -> (a -> b -> c -> d) -> a -> d inter fb fc f3d x = f3d x (fb x) (fc x) {-# INLINE inter #-} -- | A variant of the 'inter' with swapped two first arguments. The following takes place: -- > swapinter f g == inter g f swapinter :: (a -> c) -> (a -> b) -> (a -> b -> c -> d) -> a -> d swapinter fc fb f3d x = f3d x (fb x) (fc x) {-# INLINE swapinter #-} -- | A variant of 'inter' with \'stricter\' calculation scheme. Can be in many cases more efficient. inter' :: (a -> b) -> (a -> c) -> (a -> b -> c -> d) -> a -> d inter' fb fc f3d !x = f3d x (fb x) (fc x) {-# INLINE inter' #-} -- | A variant of the 'swapinter' with \'stricter\' calculation scheme. Can be in many cases more efficient. swapinter' :: (a -> c) -> (a -> b) -> (a -> b -> c -> d) -> a -> d swapinter' fc fb f3d !x = f3d x (fb x) (fc x) {-# INLINE swapinter' #-}