diff options
author | Kierán Meinhardt <kmein@posteo.de> | 2024-10-12 12:25:55 +0200 |
---|---|---|
committer | Kierán Meinhardt <kmein@posteo.de> | 2024-10-12 12:26:22 +0200 |
commit | 0878de24223e51adfc91ea3a2a8e8f2cdc21debb (patch) | |
tree | 5b114c8e8d6f4e1b4991f742d7736bcdcb05dbb8 | |
parent | 7555ced42cf727639ed2767e930afbc8eaf35615 (diff) |
unions are a set of possible types
-rw-r--r-- | autotypes/src/AutoTypes/Unify.hs | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/autotypes/src/AutoTypes/Unify.hs b/autotypes/src/AutoTypes/Unify.hs index 5d611d3..2abde6a 100644 --- a/autotypes/src/AutoTypes/Unify.hs +++ b/autotypes/src/AutoTypes/Unify.hs @@ -20,6 +20,7 @@ import Data.List (intercalate, nub) import Data.Map (Map) import qualified Data.Map as M import qualified Data.Map.Merge.Lazy as M +import qualified Data.Set as S import qualified Data.Text as T import Data.Time.Clock import Data.Time.Format.ISO8601 @@ -33,7 +34,7 @@ data ScalarType | Number | DateTime | Bool - deriving (Eq, Show) + deriving (Eq, Ord, Show) scalarTypeString :: ScalarType -> String scalarTypeString String = "string" @@ -46,9 +47,9 @@ data T | Object (Map String T) | Option (Maybe T) | Scalar ScalarType - | Union [T] + | Union (S.Set T) | Reference String - deriving (Eq, Show) + deriving (Eq, Ord, Show) instance A.ToJSON T where toJSON (List t) = A.object [K.fromString "type" A..= "array", K.fromString "items" A..= A.toJSON t] @@ -79,19 +80,18 @@ toString_ n (Option (Just t)) = map (second (++ "?")) (toString_ n t) indent n = (++) (replicate (4 * n) ' ') -union :: [T] -> T -union ts = - case ts of - [t] -> t - ts -> Union ts +union :: S.Set T -> T +union ts + | S.size ts == 1 = S.findMin ts + | otherwise = Union ts unify1 :: T -> T -> [T] unify1 (Scalar n) (Scalar m) | n == m = [Scalar n] - | otherwise = [union [Scalar n, Scalar m]] + | otherwise = [union (S.fromList [Scalar n, Scalar m])] unify1 (Reference i) (Reference j) | i == j = [Reference i] - | otherwise = [union [Reference i, Reference j]] + | otherwise = [union (S.fromList [Reference i, Reference j])] unify1 l@(Object ls) r@(Object rs) = let os = ( map Object . traverse id $ @@ -107,7 +107,7 @@ unify1 l@(Object ls) r@(Object rs) = in os ++ ( if l `subst` r || r `subst` l then [] - else [union [l, r]] + else [union (S.fromList [l, r])] ) unify1 (Option Nothing) (Option Nothing) = [Option Nothing] unify1 (Option (Just l)) (Option Nothing) = [Option (Just l)] @@ -123,14 +123,14 @@ unify1 (List (Just l)) (List (Just r)) = else if l `subst` r then [List (Just r)] - else [List (Just (union [l, r]))] + else [List (Just (union (S.fromList [l, r])))] unify1 l (Option Nothing) = [Option (Just l)] unify1 l (Option (Just r)) = map (Option . Just) (unify1 l r) unify1 (Option (Just l)) r = map (Option . Just) (unify1 l r) -unify1 (Union ls) (Union rs) = [union (ls ++ rs)] -unify1 (Union ls) r = [union (ls ++ [r])] -unify1 l (Union rs) = [union ([l] ++ rs)] -unify1 l r = [union [l, r]] +unify1 (Union ls) (Union rs) = [union (ls `S.union` rs)] +unify1 (Union ls) r = [union (S.insert r ls)] +unify1 l (Union rs) = [union (S.insert l rs)] +unify1 l r = [union (S.fromList [l, r])] subst :: T -> T -> Bool subst (Object l) (Object r) = |