git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Polymorphic object update
commit939f826b9951865b47c3a47a0d25b1fb01e26707 authorPhil Freeman <paf31@cantab.net> dateWed 27 Nov 2013, 17:53 (13 years ago) parent33268ae
4 files changed+18−14
examples/passing/ObjectUpdate.ps+6−1 purescript.cabal+1−1 src/Language/PureScript/TypeChecker/Types.hs+11−8 src/Language/PureScript/Types.hs−4
examples/passing/ObjectUpdate.ps+6−1
@@ -6,4 +6,9 @@ update2 = \o -> o { foo = "Foo" }
66replace = \o -> case o of
77 { foo = "Foo" } -> o { foo = "Bar" }
88 { 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 @@
11name: purescript
2−version: 0.1.11
2+version: 0.1.12
33cabal-version: >=1.8
44build-type: Simple
55license: MIT
src/Language/PureScript/TypeChecker/Types.hs+11−8
@@ -295,15 +295,14 @@ infer' m (ObjectLiteral ps) = do
295295 lift $ ensureNoDuplicateProperties ps
296296 ts <- mapM (infer m . snd) ps
297297 let fields = zipWith (\(name, _) t -> (name, t)) ps ts
298− return $ Object $ typesToRow fields
298+ return $ Object $ rowFromList (fields, REmpty)
299299infer' m (ObjectUpdate o ps) = do
300300 lift $ ensureNoDuplicateProperties ps
301− obj <- infer m o
302301 row <- fresh
303− ts <- mapM (infer m . snd) ps
304− let tys = zipWith (\(name, _) t -> (name, t)) ps ts
305− obj ~~ Object (rowFromList (tys, row))
306− return obj
302+ newTys <- zipWith (\(name, _) t -> (name, t)) ps <$> mapM (infer m . snd) ps
303+ oldTys <- zip (map fst ps) <$> replicateM (length ps) fresh
304+ check m o $ Object $ rowFromList (oldTys, row)
305+ return $ Object $ rowFromList (newTys, row)
307306infer' m (Indexer index val) = do
308307 el <- fresh
309308 check m index Number
@@ -662,9 +661,13 @@ check' m (IfThenElse cond th el) ty = do
662661check' m (ObjectLiteral ps) (Object row) = do
663662 lift $ ensureNoDuplicateProperties ps
664663 checkProperties m ps row False
665−check' m (ObjectUpdate obj ps) objTy@(Object row) = do
664+check' m (ObjectUpdate obj ps) (Object row) = do
666665 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)))
668671 checkProperties m ps row True
669672check' m (Accessor prop val) ty = do
670673 rest <- fresh
src/Language/PureScript/Types.hs−4
@@ -44,10 +44,6 @@ data Row
4444 | RCons String Type Row
4545 | RSkolem Int deriving (Show, Eq, Data, Typeable)
4646
47−typesToRow :: [(String, Type)] -> Row
48−typesToRow [] = REmpty
49−typesToRow ((name, ty):tys) = RCons name ty (typesToRow tys)
50−
5147rowToList :: Row -> ([(String, Type)], Row)
5248rowToList (RCons name ty row) = let (tys, rest) = rowToList row
5349 in ((name, ty):tys, rest)