git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Fix some typechecker bugs
commit78f85b3f37ab4ed400fcb09844d7edc597cbd454 authorPhil Freeman <paf31@cantab.net> dateMon 30 Sep 2013, 21:23 (13 years ago) parent8c17718
10 files changed+136−75
src/Main.hs+1−2 src/PureScript/CodeGen.hs+9−2 src/PureScript/Declarations.hs+1−1 src/PureScript/Parser/Declarations.hs+13−6 src/PureScript/Parser/Values.hs+10−7 src/PureScript/TypeChecker.hs+10−8 src/PureScript/TypeChecker/Kinds.hs+53−34 src/PureScript/TypeChecker/Monad.hs+2−2 src/PureScript/TypeChecker/Types.hs+35−12 src/PureScript/Values.hs+2−1
src/Main.hs+1−2
@@ -15,7 +15,6 @@
1515module Main where
1616
1717import PureScript
18−import Text.Parsec
1918import Data.Maybe (mapMaybe)
2019import Data.List (intercalate)
2120import System.Console.CmdTheLine
@@ -26,7 +25,7 @@ import qualified System.IO.UTF8 as U
2625compile :: [FilePath] -> Maybe FilePath -> IO ()
2726compile inputFiles outputFile = do
2827 input <- fmap concat $ mapM U.readFile inputFiles
29− let ast = parse parseDeclarations "" input
28+ let ast = parseDeclarations input
3029 case ast of
3130 Left err -> do
3231 U.print err
src/PureScript/CodeGen.hs+9−2
@@ -23,7 +23,10 @@ import PureScript.Declarations
2323declToJs :: Declaration -> Maybe String
2424declToJs (ValueDeclaration name val) = Just $ "var " ++ name ++ " = " ++ valueToJs val ++ ";"
2525declToJs (DataDeclaration dcs@(DataConstructors { dataConstructors = ctors })) =
26− Just $ concatMap (\(ctor, _) -> "var " ++ ctor ++ " = function (value) { return { ctor: '" ++ ctor ++ "', value: value }; };") ctors
26+ Just $ flip concatMap ctors $ \(ctor, maybeTy) ->
27+ case maybeTy of
28+ Nothing -> "var " ++ ctor ++ " = { ctor: '" ++ ctor ++ "' };"
29+ Just _ -> "var " ++ ctor ++ " = function (value) { return { ctor: '" ++ ctor ++ "', value: value }; };"
2730declToJs _ = Nothing
2831
2932valueToJs :: Value -> String
@@ -77,7 +80,11 @@ binaryOperatorString Concat = "+"
7780
7881binderToJs :: Int -> Int -> Binder -> String -> (String, Int)
7982binderToJs varName fresh (VarBinder s) done = ("var " ++ s ++ " = _" ++ show varName ++ "; " ++ done, fresh)
80−binderToJs varName fresh (ConstructorBinder ctor b) done =
83+binderToJs varName fresh (NullaryBinder ctor) done =
84+ ("if (_" ++ show varName ++ ".ctor === \"" ++ ctor ++ "\") {"
85+ ++ done
86+ ++ "}", fresh)
87+binderToJs varName fresh (UnaryBinder ctor b) done =
8188 ("if (_" ++ show varName ++ ".ctor === \"" ++ ctor ++ "\") {"
8289 ++ "var _" ++ show fresh' ++ " = _" ++ show varName ++ ".value;"
8390 ++ js
src/PureScript/Declarations.hs+1−1
@@ -28,5 +28,5 @@ data Declaration
2828data DataConstructors = DataConstructors
2929 { typeConstructorName :: String
3030 , typeArguments :: [String]
31− , dataConstructors :: [(String, Type)]
31+ , dataConstructors :: [(String, Maybe Type)]
3232 } deriving Show
src/PureScript/Parser/Declarations.hs+13−6
@@ -17,12 +17,16 @@ module PureScript.Parser.Declarations (
1717 parseDeclarations
1818) where
1919
20−import PureScript.Values
21−import PureScript.Types
22−import PureScript.Parser.Common
20+import Data.Char
21+import Data.List
22+import Data.Function
2323import Control.Applicative
2424import qualified Text.Parsec as P
2525import Control.Arrow (Arrow(..))
26+
27+import PureScript.Values
28+import PureScript.Types
29+import PureScript.Parser.Common
2630import PureScript.Declarations
2731import PureScript.Parser.Values
2832import PureScript.Parser.Types
@@ -33,7 +37,7 @@ parseDataDeclaration = do
3337 name <- properName
3438 tyArgs <- many identifier
3539 lexeme $ P.char '='
36− ctors <- P.sepBy1 ((,) <$> properName <*> parseType) (lexeme $ P.char '|')
40+ ctors <- P.sepBy1 ((,) <$> properName <*> P.optionMaybe parseType) (lexeme $ P.char '|')
3741 return $ DataDeclaration $ DataConstructors name tyArgs ctors
3842
3943parseValueDeclaration :: P.Parsec String () Declaration
@@ -43,5 +47,8 @@ parseDeclaration :: P.Parsec String () Declaration
4347parseDeclaration = parseDataDeclaration
4448 P.<|> parseValueDeclaration
4549
46−parseDeclarations :: P.Parsec String () [Declaration]
47−parseDeclarations = whiteSpace *> P.sepEndBy parseDeclaration semi <* P.eof
50+parseDeclarations :: String -> Either P.ParseError [Declaration]
51+parseDeclarations = mapM (P.parse (parseDeclaration <* whiteSpace <* P.eof) "Declaration") . splitFileIntoDeclarations
52+
53+splitFileIntoDeclarations :: String -> [String]
54+splitFileIntoDeclarations = map unlines . filter (not . all isSpace . head) . groupBy ((==) `on` (all isSpace)) . lines
src/PureScript/Parser/Values.hs+10−7
@@ -62,7 +62,7 @@ parseApp = App <$> parseValue
6262 <*> (C.parens $ C.commaSep parseValue)
6363
6464parseVar :: P.Parsec String () Value
65−parseVar = Var <$> C.identifier
65+parseVar = Var <$> (C.identifier <|> C.properName)
6666
6767parseCase :: P.Parsec String () Value
6868parseCase = Case <$> P.between (C.reserved "case") (C.reserved "of") parseValue
@@ -88,9 +88,9 @@ parseValueAtom = P.choice $ map P.try
8888 , C.parens parseValue ]
8989
9090parseValue :: P.Parsec String () Value
91−parseValue = buildExpressionParser operators $ C.fold (C.lexeme typedValue') (C.lexeme funArgs) App
91+parseValue = buildExpressionParser operators $ C.fold (C.lexeme typedValue) (C.lexeme funArgs) App
9292 where
93− typedValue' = C.augment parseValueAtom parseTypeAnnotation TypedValue
93+ typedValue = C.augment parseValueAtom parseTypeAnnotation TypedValue
9494 funArgs = C.parens $ C.commaSep parseValue
9595 parseTypeAnnotation = C.lexeme (P.string "::") *> parseType
9696 operators = [ [ Postfix $ (Accessor <$> (C.dot *> C.identifier)) ]
@@ -168,9 +168,11 @@ parseStatement = P.choice $ map P.try
168168parseVarBinder :: P.Parsec String () Binder
169169parseVarBinder = VarBinder <$> C.lexeme C.identifier
170170
171−parseConstructorBinder :: P.Parsec String () Binder
172−parseConstructorBinder = ConstructorBinder <$> C.lexeme C.properName
173− <*> parseBinder
171+parseNullaryBinder :: P.Parsec String () Binder
172+parseNullaryBinder = NullaryBinder <$> C.lexeme C.properName
173+
174+parseUnaryBinder :: P.Parsec String () Binder
175+parseUnaryBinder = UnaryBinder <$> C.lexeme C.properName <*> parseBinder
174176
175177parseObjectBinder :: P.Parsec String () Binder
176178parseObjectBinder = ObjectBinder <$> C.braces (C.commaSep parseIdentifierAndBinder)
@@ -185,6 +187,7 @@ parseIdentifierAndBinder = do
185187parseBinder :: P.Parsec String () Binder
186188parseBinder = P.choice $ map P.try
187189 [ parseVarBinder
188− , parseConstructorBinder
190+ , parseUnaryBinder
191+ , parseNullaryBinder
189192 , parseObjectBinder
190193 , C.parens parseBinder ]
src/PureScript/TypeChecker.hs+10−8
@@ -27,6 +27,7 @@ import PureScript.TypeChecker.Kinds
2727import PureScript.TypeChecker.Types
2828
2929import Data.List
30+import Data.Maybe
3031import Data.Function
3132
3233import PureScript.Values
@@ -47,20 +48,21 @@ typeCheck (DataDeclaration dcs@(DataConstructors
4748 })) = rethrow (("Error in type constructor " ++ name ++ ": ") ++) $ do
4849 env <- get
4950 guardWith (name ++ " is already defined") $ not $ M.member name (types env)
50− kinds <- kindsOf args (map snd ctors)
51− let ctorKind = foldl FunKind Star kinds
51+ ctorKind <- kindsOf name args (catMaybes $ map snd ctors)
5252 put $ env { types = M.insert name ctorKind (types env) }
53− flip mapM_ ctors $ \(dctor, ty) -> rethrow (("Error in data constructor " ++ name ++ ": ") ++) $ do
54− env' <- get
55− guardWith (dctor ++ " is already defined") $ not $ flip M.member (names env') dctor
56− let ctorType = Function [ty] $ foldl TypeApp (TypeConstructor name) (map TypeVar args)
57− put $ env' { names = M.insert dctor ctorType (names env) }
53+ flip mapM_ ctors $ \(dctor, maybeTy) ->
54+ rethrow (("Error in data constructor " ++ name ++ ": ") ++) $ do
55+ env' <- get
56+ guardWith (dctor ++ " is already defined") $ not $ flip M.member (names env') dctor
57+ let retTy = foldl TypeApp (TypeConstructor name) (map TypeVar args)
58+ let dctorTy = maybe retTy (\ty -> Function [ty] retTy) maybeTy
59+ put $ env' { names = M.insert dctor dctorTy (names env') }
5860typeCheck (ValueDeclaration name val) = rethrow (("Error in declaration " ++ name ++ ": ") ++) $ do
5961 env <- get
6062 case M.lookup name (names env) of
6163 Just ty -> throwError $ name ++ " is already defined"
6264 Nothing -> do
63− ty <- typeOf val
65+ ty <- typeOf name val
6466 put (env { names = M.insert name ty (names env) })
6567
6668typeCheckAll :: [Declaration] -> Check ()
src/PureScript/TypeChecker/Kinds.hs+53−34
@@ -35,65 +35,82 @@ import qualified Control.Category as C
3535
3636import qualified Data.Map as M
3737
38−data KindConstraint = KindConstraint Int Kind deriving Show
38+data KindConstraint = KindConstraint Int Kind
39+
40+instance Show KindConstraint where
41+ show (KindConstraint n k) = show n ++ " = " ++ show k
3942
4043newtype KindSolution = KindSolution { runKindSolution :: Int -> Kind }
4144
4245emptyKindSolution :: KindSolution
4346emptyKindSolution = KindSolution KUnknown
4447
45−kindsOf :: [String] -> [Type] -> Check [Kind]
46−kindsOf args ts = do
47− (cs, _, m) <- kindConstraintsAll 0 M.empty ts
48− solution <- solveKindConstraints cs emptyKindSolution
49− return $ map (maybe Star starIfUnknown . fmap (runKindSolution solution) . flip M.lookup m) args
48+kindsOf :: String -> [String] -> [Type] -> Check Kind
49+kindsOf name args ts = do
50+ let tyCon = 0
51+ let nargs = [1..length args]
52+ (cs, ns, _, m) <- kindConstraintsAll (length args + 1) (M.insert name tyCon $ M.fromList (zipWith (,) args nargs)) ts
53+ let extraConstraints = KindConstraint tyCon (foldr FunKind Star (map KUnknown nargs)) : map (flip KindConstraint Star) ns
54+ solution <- solveKindConstraints (extraConstraints ++ cs) emptyKindSolution
55+ return $ starIfUnknown $ runKindSolution solution 0
5056
5157starIfUnknown :: Kind -> Kind
5258starIfUnknown (KUnknown _) = Star
5359starIfUnknown (FunKind k1 k2) = FunKind (starIfUnknown k1) (starIfUnknown k2)
5460starIfUnknown k = k
5561
56−kindConstraintsAll :: Int -> M.Map String Int -> [Type] -> Check ([KindConstraint], [Int], M.Map String Int)
57−kindConstraintsAll _ m [] = return ([], [], m)
62+kindConstraintsAll :: Int -> M.Map String Int -> [Type] -> Check ([KindConstraint], [Int], Int, M.Map String Int)
63+kindConstraintsAll n m [] = return ([], [], n, m)
5864kindConstraintsAll n m (t:ts) = do
59− (cs, n', m') <- kindConstraints n m t
60− (cs', ns, m'') <- kindConstraintsAll (n' + 1) m' ts
61− return ((KindConstraint n' Star) : cs ++ cs', n':ns, m'')
65+ (cs, n1, max1, m') <- kindConstraints n m t
66+ (cs', ns, max2, m'') <- kindConstraintsAll (max1 + 1) m' ts
67+ return ((KindConstraint n1 Star) : cs ++ cs', n1:ns, max2, m'')
6268
63−kindConstraints :: Int -> M.Map String Int -> Type -> Check ([KindConstraint], Int, M.Map String Int)
69+kindConstraints :: Int -> M.Map String Int -> Type -> Check ([KindConstraint], Int, Int, M.Map String Int)
6470kindConstraints n m (Array t) = do
65− (cs, n', m') <- kindConstraints n m t
66− return ((KindConstraint n' Star) : (KindConstraint (n' + 1) Star) : cs, n' + 1, m')
71+ let me = n
72+ (cs, n1, max1, m') <- kindConstraints (n + 1) m t
73+ return ((KindConstraint n1 Star) : (KindConstraint me Star) : cs, me, max1, m')
6774kindConstraints n m (Object row) = do
6875 let me = n
69− (cs, row, m') <- kindConstraintsForRow (n + 2) m row
70− return ((KindConstraint me Star) : (KindConstraint row Row) : cs, me, m')
76+ (cs, row, max1, m') <- kindConstraintsForRow (n + 1) m row
77+ return ((KindConstraint me Star) : (KindConstraint row Row) : cs, me, max1, m')
7178kindConstraints n m (Function args ret) = do
72− (cs, ns, m') <- kindConstraintsAll n m args
73− let next = maximum ns + 1
74− (cs', retN, m'') <- kindConstraints next m' ret
75− let me = retN + 1
76− return ((KindConstraint retN Star) : (KindConstraint me Star) : (map (flip KindConstraint Star) ns) ++ cs, me, m'')
79+ let me = n
80+ (cs, ns, max1, m') <- kindConstraintsAll (n + 1) m args
81+ (cs', retN, max2, m'') <- kindConstraints (max1 + 1) m' ret
82+ return ((KindConstraint retN Star) : (KindConstraint me Star) : (map (flip KindConstraint Star) ns) ++ cs, me, max2, m'')
7783kindConstraints n m (TypeVar v) =
78− let
79− n' = maybe n id (M.lookup v m)
80− in return ([], n', M.insert v n' m)
84+ let n' = maybe n id (M.lookup v m)
85+ in return ([], n', n, M.insert v n' m)
8186kindConstraints n m (TypeConstructor v) = do
8287 env <- get
83− kind <- maybe (throwError "Unknown type constructor") return (M.lookup v (types env))
84− return ([KindConstraint n kind], n, m)
88+ kind <- case M.lookup v m of
89+ Nothing -> case M.lookup v (types env) of
90+ Nothing -> throwError $ "Unknown type constructor '" ++ v ++ "'"
91+ Just k -> return k
92+ Just u -> return (KUnknown u)
93+ return ([KindConstraint n kind], n, n, m)
8594kindConstraints n m (TypeApp t1 t2) = do
86− (cs1, n1, m1) <- kindConstraints n m t1
87− (cs2, n2, m2) <- kindConstraints (n1 + 1) m1 t2
88− return ((KindConstraint n1 (FunKind (KUnknown n2) (KUnknown (n2 + 1)))) : cs1 ++ cs2, n2 + 1, m2)
89−kindConstraints n m _ = return ([KindConstraint n Star], n, m)
90−
91−kindConstraintsForRow :: Int -> M.Map String Int -> Row -> Check ([KindConstraint], Int, M.Map String Int)
92−kindConstraintsForRow = undefined
95+ let me = n
96+ (cs1, n1, max1, m1) <- kindConstraints (n + 1) m t1
97+ (cs2, n2, max2, m2) <- kindConstraints (max1 + 1) m1 t2
98+ return ((KindConstraint n1 (FunKind (KUnknown n2) (KUnknown me))) : cs1 ++ cs2, me, max2, m2)
99+kindConstraints n m _ = return ([KindConstraint n Star], n, n, m)
100+
101+kindConstraintsForRow :: Int -> M.Map String Int -> Row -> Check ([KindConstraint], Int, Int, M.Map String Int)
102+kindConstraintsForRow n m (RowVar v) =
103+ let n' = maybe n id (M.lookup v m)
104+ in return ([KindConstraint n' Row], n', n, M.insert v n' m)
105+kindConstraintsForRow n m REmpty = return ([KindConstraint n Row], n, n, m)
106+kindConstraintsForRow n m (RCons _ ty row) = do
107+ (cs1, n1, max1, m1) <- kindConstraints (n + 1) m ty
108+ (cs2, n2, max2, m2) <- kindConstraintsForRow (max1 + 1) m1 row
109+ return ((KindConstraint n Row) : (KindConstraint n1 Star) : (KindConstraint n2 Row) : cs1 ++ cs2, n, max2, m2)
93110
94111solveKindConstraints :: [KindConstraint] -> KindSolution -> Check KindSolution
95112solveKindConstraints [] s = return s
96−solveKindConstraints (KindConstraint n k:cs) s = do
113+solveKindConstraints all@(KindConstraint n k:cs) s = do
97114 guardWith "Occurs check failed" $ not $ kindOccursCheck n k
98115 let s' = KindSolution $ replaceUnknownKind n k . runKindSolution s
99116 cs' <- fmap concat $ mapM (substituteKindConstraint n k) cs
@@ -112,6 +129,7 @@ replaceUnknownKind n k = f
112129 f other = other
113130
114131unifyKinds :: Kind -> Kind -> Check [KindConstraint]
132+unifyKinds (KUnknown u1) (KUnknown u2) | u1 == u2 = return []
115133unifyKinds (KUnknown u) k = do
116134 guardWith "Occurs check failed" $ not $ kindOccursCheck u k
117135 return [KindConstraint u k]
@@ -119,6 +137,7 @@ unifyKinds k (KUnknown u) = do
119137 guardWith "Occurs check failed" $ not $ kindOccursCheck u k
120138 return [KindConstraint u k]
121139unifyKinds Star Star = return []
140+unifyKinds Row Row = return []
122141unifyKinds (FunKind k1 k2) (FunKind k3 k4) = do
123142 cs1 <- unifyKinds k1 k3
124143 cs2 <- unifyKinds k2 k4
src/PureScript/TypeChecker/Monad.hs+2−2
@@ -35,8 +35,8 @@ emptyEnvironment = Environment M.empty M.empty
3535
3636newtype Check a = Check { unCheck :: StateT Environment (Either String) a } deriving (Functor, Monad, Applicative, MonadPlus, MonadState Environment, MonadError String)
3737
38−check :: Check a -> Either String a
39−check = flip evalStateT emptyEnvironment . unCheck
38+check :: Check a -> Either String (a, Environment)
39+check = flip runStateT emptyEnvironment . unCheck
4040
4141guardWith :: (MonadError e m) => e -> Bool -> m ()
4242guardWith _ True = return ()
src/PureScript/TypeChecker/Types.hs+35−12
@@ -18,6 +18,8 @@ module PureScript.TypeChecker.Types (
1818 typeOf
1919) where
2020
21+import Debug.Trace
22+
2123import Data.List
2224import Data.Function
2325
@@ -43,10 +45,11 @@ newtype TypeSolution = TypeSolution { runTypeSolution :: (Int -> Type, Int -> Ro
4345emptyTypeSolution :: TypeSolution
4446emptyTypeSolution = TypeSolution (TUnknown, RUnknown)
4547
46−typeOf :: Value -> Check Type
47−typeOf val = do
48− (cs, n, _) <- typeConstraints 0 M.empty val
49− solution <- solveTypeConstraints cs emptyTypeSolution
48+typeOf :: String -> Value -> Check Type
49+typeOf name val = do
50+ let me = 0
51+ (cs, n, _) <- typeConstraints 1 (M.singleton name me) val
52+ solution <- solveTypeConstraints ((TypeConstraint me (TUnknown n)) : cs) emptyTypeSolution
5053 return $ varIfUnknown $ fst (runTypeSolution solution) n
5154
5255varIfUnknown :: Type -> Type
@@ -213,25 +216,44 @@ symBinOpConstraints ty left right result = [TypeConstraint left ty, TypeConstrai
213216typeConstraintsForBinder :: Int -> M.Map String Int -> Int -> Binder -> Check ([TypeConstraint], Int, M.Map String Int)
214217typeConstraintsForBinder n m val (VarBinder name) =
215218 return ([TypeConstraint n (TUnknown val)], n, M.insert name n m)
216−typeConstraintsForBinder n m val (ConstructorBinder ctor binder) = do
219+typeConstraintsForBinder n m val (NullaryBinder ctor) = do
220+ env <- get
221+ case M.lookup ctor (names env) of
222+ Just ret -> do
223+ let (ret', max1) = replaceVarsWithUnknowns n ret
224+ return ([TypeConstraint val ret'], max1, m)
225+ _ -> throwError $ "Constructor " ++ ctor ++ " is not defined"
226+typeConstraintsForBinder n m val (UnaryBinder ctor binder) = do
217227 env <- get
218228 case M.lookup ctor (names env) of
219229 Just f@(Function [ty] ret) -> do
220230 let obj = n
221− let (Function [ty'] ret', max1) = replaceVarsWithUnknowns n f
231+ let (Function [ty'] ret', max1) = replaceVarsWithUnknowns (n + 1) f
222232 (cs, max2, m1) <- typeConstraintsForBinder (max1 + 1) m obj binder
223233 return ((TypeConstraint val ret') : (TypeConstraint obj ty') : cs, max2, m1)
224− Just _ -> throwError $ ctor ++ " is not a constructor"
234+ Just _ -> throwError $ ctor ++ " is not a unary constructor"
225235 _ -> throwError $ "Constructor " ++ ctor ++ " is not defined"
226−typeConstraintsForBinder n m val (ObjectBinder props) = do undefined
236+typeConstraintsForBinder n m val (ObjectBinder props) = do
237+ let row = n
238+ let rest = n + 1
239+ (cs, max1, m1) <- typeConstraintsForProperties (n + 2) m row (RUnknown rest) props
240+ return ((TypeConstraint val (Object (RUnknown row))) : cs, max1, m1)
241+ where
242+ typeConstraintsForProperties :: Int -> M.Map String Int -> Int -> Row -> [(String, Binder)] -> Check ([TypeConstraint], Int, M.Map String Int)
243+ typeConstraintsForProperties n m nrow row [] = return ([RowConstraint nrow row], n, m)
244+ typeConstraintsForProperties n m nrow row ((name, binder):binders) = do
245+ let propTy = n
246+ (cs1, max1, m1) <- typeConstraintsForBinder (n + 1) m propTy binder
247+ (cs2, max2, m2) <- typeConstraintsForProperties (max1 + 1) m1 nrow (RCons name (TUnknown propTy) row) binders
248+ return (cs1 ++ cs2, max2, m2)
227249
228250typeConstraintsForBinders :: Int -> M.Map String Int -> Int -> Int -> [(Binder, Value)] -> Check ([TypeConstraint], Int)
229251typeConstraintsForBinders n _ _ _ [] = return ([], n)
230252typeConstraintsForBinders n m nval ret ((binder, val):bs) = do
231253 (cs1, max1, m1) <- typeConstraintsForBinder n m nval binder
232254 (cs2, n2, max2) <- typeConstraints (max1 + 1) m1 val
233− (cs3, max2) <- typeConstraintsForBinders (max2 + 1) m nval ret bs
234− return ((TypeConstraint n2 (TUnknown ret)) : cs1 ++ cs2 ++ cs3, max2)
255+ (cs3, max3) <- typeConstraintsForBinders (max2 + 1) m nval ret bs
256+ return ((TypeConstraint n2 (TUnknown ret)) : cs1 ++ cs2 ++ cs3, max3)
235257
236258typeConstraintsForStatement :: Int -> M.Map String Int -> M.Map String Int -> Int -> Statement -> Check ([TypeConstraint], Bool, Int, M.Map String Int)
237259typeConstraintsForStatement n m mass ret (VariableIntroduction name val) = do
@@ -291,7 +313,7 @@ typeConstraintsAll n m (t:ts) = do
291313
292314solveTypeConstraints :: [TypeConstraint] -> TypeSolution -> Check TypeSolution
293315solveTypeConstraints [] s = return s
294−solveTypeConstraints (TypeConstraint n t:cs) s = do
316+solveTypeConstraints all@(TypeConstraint n t:cs) s = do
295317 guardWith "Occurs check failed" $ not $ typeOccursCheck n t
296318 let s' = let (f, g) = runTypeSolution s
297319 in TypeSolution (replaceTypeInType n t . f, replaceTypeInRow n t . g)
@@ -343,8 +365,9 @@ replaceRowInRow n r (RCons name ty row) = RCons name (replaceRowInType n r ty) (
343365replaceRowInRow _ _ other = other
344366
345367unifyTypes :: Type -> Type -> Check [TypeConstraint]
368+unifyTypes (TUnknown u1) (TUnknown u2) | u1 == u2 = return []
346369unifyTypes (TUnknown u) t = do
347− guardWith "Occurs check failed" $ not $ typeOccursCheck u t
370+ guardWith "Occurs check failed for " $ not $ typeOccursCheck u t
348371 return [TypeConstraint u t]
349372unifyTypes t (TUnknown u) = do
350373 guardWith "Occurs check failed" $ not $ typeOccursCheck u t
src/PureScript/Values.hs+2−1
@@ -76,5 +76,6 @@ data Statement
7676
7777data Binder
7878 = VarBinder String
79− | ConstructorBinder String Binder
79+ | NullaryBinder String
80+ | UnaryBinder String Binder
8081 | ObjectBinder [(String, Binder)] deriving Show