type-machine 0.1.0.1 → 0.1.0.2
raw patch · 3 files changed
+49/−14 lines, 3 filesPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
API changes (from Hackage documentation)
+ TypeMachine.Functions: data Selector
+ TypeMachine.Functions: instance GHC.Classes.Eq TypeMachine.Functions.Selector
+ TypeMachine.Functions: instance GHC.Internal.Show.Show TypeMachine.Functions.Selector
+ TypeMachine.Functions: intersectionWithSelector :: (String -> Selector) -> Type -> Type -> TM Type
+ TypeMachine.Functions: unionWithSelector :: (String -> Selector) -> Type -> Type -> TM Type
Files
- CHANGELOG.md +4/−0
- src/TypeMachine/Functions.hs +43/−12
- type-machine.cabal +2/−2
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Changelog for `type-machine` +## 0.1.0.2 - 2025-09-02++- Add `union`/`intersectionWithSelector`+ ## 0.1.0.1 - 2025-08-11 - Expose 'Liftable' module
src/TypeMachine/Functions.hs view
@@ -23,6 +23,11 @@ apply, applyMany, + -- * With Selector+ intersectionWithSelector,+ unionWithSelector,+ Selector,+ -- * Utils keysOf, )@@ -41,6 +46,7 @@ import TypeMachine.Log import TypeMachine.TM import TypeMachine.Type+import Prelude hiding (Either (..)) -- | Mark fields are required --@@ -111,12 +117,7 @@ -- data _ = { b :: Int } -- @ intersection :: Type -> Type -> TM Type-intersection a b = do- failIfHasTypeVariables a- failIfHasTypeVariables b- let finalType = a{fields = Map.intersection (fields a) (fields b)}- logIfEmptyType finalType- return finalType+intersection = intersectionWithSelector (const Left) -- | Keep the fields present in both types --@@ -130,9 +131,25 @@ -- data _ = { b :: String } -- @ intersection' :: Type -> Type -> TM Type-intersection' = flip intersection+intersection' = intersectionWithSelector (const Right) {-# INLINE intersection' #-} +-- | Variant of 'intersection' where user can decide which value to keep (the left object's or the right's) in case of overlap+intersectionWithSelector :: (String -> Selector) -> Type -> Type -> TM Type+intersectionWithSelector select a b = do+ failIfHasTypeVariables a+ failIfHasTypeVariables b+ let finalType =+ a+ { fields =+ Map.intersectionWithKey+ (\key aField bField -> if select key == Left then aField else bField)+ (fields a)+ (fields b)+ }+ logIfEmptyType finalType+ return finalType+ -- | Merge two types together -- -- If keys overlap, prefer the type of the left type@@ -145,10 +162,7 @@ -- data _ = { a :: Int, b :: Int, c :: Void } -- @ union :: Type -> Type -> TM Type-union a b = do- failIfHasTypeVariables a- failIfHasTypeVariables b- return $ a{fields = Map.union (fields a) (fields b)}+union = unionWithSelector (const Left) -- | Merge two types together --@@ -162,9 +176,23 @@ -- data _ = { a :: Int, b :: String, c :: Void } -- @ union' :: Type -> Type -> TM Type-union' = flip union+union' = unionWithSelector (const Right) {-# INLINE union' #-} +-- | Variant of 'union' where user can decide which value to keep (the left object's or the right's) in case of overlap+unionWithSelector :: (String -> Selector) -> Type -> Type -> TM Type+unionWithSelector select a b = do+ failIfHasTypeVariables a+ failIfHasTypeVariables b+ return $+ a+ { fields =+ Map.unionWithKey+ (\key aField bField -> if select key == Left then aField else bField)+ (fields a)+ (fields b)+ }+ -- | Get the names of the fields in in type -- -- @@@ -273,6 +301,9 @@ -- @ applyMany :: [Q TH.Type] -> Type -> TM Type applyMany typeArgs ty = foldM (flip apply) ty typeArgs++-- | Selector for functions like 'intersectionWithSelector'+data Selector = Left | Right deriving (Eq, Show) -- Utils for logs
type-machine.cabal view
@@ -1,11 +1,11 @@ cabal-version: 2.2 --- This file has been generated from package.yaml by hpack version 0.38.0.+-- This file has been generated from package.yaml by hpack version 0.38.1. -- -- see: https://github.com/sol/hpack name: type-machine-version: 0.1.0.1+version: 0.1.0.2 synopsis: Type-level functions for record types category: Types homepage: https://github.com/Arthi-chaud/type-machine#readme