git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Polymorphic object update
939f826Phil Freeman
examples/passing/ObjectUpdate.ps+6−1
@@ -6,4 +6,9 @@ update2 = \o -> o { foo = "Foo" }
6replace = \o -> case o of
6replace = \o -> case o of
7 { foo = "Foo" } -> o { foo = "Bar" }
7 { foo = "Foo" } -> o { foo = "Bar" }
8 { foo = "Bar" } -> o { bar = "Baz" }
8 { foo = "Bar" } -> o { bar = "Baz" }
9− o -> o
9+ o -> o
10+
11+polyUpdate :: forall a r. { foo :: a | r } -> { foo :: String | r }
12+polyUpdate = \o -> o { foo = "Foo" }
13+
14+inferPolyUpdate = \o -> o { foo = "Foo" }
purescript.cabal+1−1
@@ -1,5 +1,5 @@
1name: purescript
1name: purescript
2−version: 0.1.11
2+version: 0.1.12
3cabal-version: >=1.8
3cabal-version: >=1.8
4build-type: Simple
4build-type: Simple
5license: MIT
5license: MIT
src/Language/PureScript/TypeChecker/Types.hs+11−8
@@ -295,15 +295,14 @@ infer' m (ObjectLiteral ps) = do
295 lift $ ensureNoDuplicateProperties ps
295 lift $ ensureNoDuplicateProperties ps
296 ts <- mapM (infer m . snd) ps
296 ts <- mapM (infer m . snd) ps
297 let fields = zipWith (\(name, _) t -> (name, t)) ps ts
297 let fields = zipWith (\(name, _) t -> (name, t)) ps ts
298− return $ Object $ typesToRow fields
298+ return $ Object $ rowFromList (fields, REmpty)
299infer' m (ObjectUpdate o ps) = do
299infer' m (ObjectUpdate o ps) = do
300 lift $ ensureNoDuplicateProperties ps
300 lift $ ensureNoDuplicateProperties ps
301− obj <- infer m o
302 row <- fresh
301 row <- fresh
303− ts <- mapM (infer m . snd) ps
302+ newTys <- zipWith (\(name, _) t -> (name, t)) ps <$> mapM (infer m . snd) ps
304− let tys = zipWith (\(name, _) t -> (name, t)) ps ts
303+ oldTys <- zip (map fst ps) <$> replicateM (length ps) fresh
305− obj ~~ Object (rowFromList (tys, row))
304+ check m o $ Object $ rowFromList (oldTys, row)
306− return obj
305+ return $ Object $ rowFromList (newTys, row)
307infer' m (Indexer index val) = do
306infer' m (Indexer index val) = do
308 el <- fresh
307 el <- fresh
309 check m index Number
308 check m index Number
@@ -662,9 +661,13 @@ check' m (IfThenElse cond th el) ty = do
662check' m (ObjectLiteral ps) (Object row) = do
661check' m (ObjectLiteral ps) (Object row) = do
663 lift $ ensureNoDuplicateProperties ps
662 lift $ ensureNoDuplicateProperties ps
664 checkProperties m ps row False
663 checkProperties m ps row False
665−check' m (ObjectUpdate obj ps) objTy@(Object row) = do
664+check' m (ObjectUpdate obj ps) (Object row) = do
666 lift $ ensureNoDuplicateProperties ps
665 lift $ ensureNoDuplicateProperties ps
667− check m obj objTy
666+ us <- zip (map fst ps) <$> replicateM (length ps) fresh
667+ let (propsToCheck, rest) = rowToList row
668+ propsToRemove = map fst ps
669+ remainingProps = filter (\(p, _) -> p `notElem` propsToRemove) propsToCheck
670+ check m obj (Object (rowFromList (us ++ remainingProps, rest)))
668 checkProperties m ps row True
671 checkProperties m ps row True
669check' m (Accessor prop val) ty = do
672check' m (Accessor prop val) ty = do
670 rest <- fresh
673 rest <- fresh
src/Language/PureScript/Types.hs−4
@@ -44,10 +44,6 @@ data Row
44 | RCons String Type Row
44 | RCons String Type Row
45 | RSkolem Int deriving (Show, Eq, Data, Typeable)
45 | RSkolem Int deriving (Show, Eq, Data, Typeable)
46
46
47−typesToRow :: [(String, Type)] -> Row
48−typesToRow [] = REmpty
49−typesToRow ((name, ty):tys) = RCons name ty (typesToRow tys)
50−
51rowToList :: Row -> ([(String, Type)], Row)
47rowToList :: Row -> ([(String, Type)], Row)
52rowToList (RCons name ty row) = let (tys, rest) = rowToList row
48rowToList (RCons name ty row) = let (tys, rest) = rowToList row
53 in ((name, ty):tys, rest)
49 in ((name, ty):tys, rest)