Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add lambda type info #1845

Merged
merged 3 commits into from
Feb 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions src/Juvix/Compiler/Internal/Extra.hs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ mkConcreteType = fmap ConcreteType . go
b' <- go b
ty' <- go ty
return (ExpressionSimpleLambda (SimpleLambda v ty' b'))
ExpressionLambda (Lambda c) -> ExpressionLambda . Lambda <$> mapM goClause c
ExpressionLambda (Lambda c ty) -> do
let _lambdaType = ty >>= go
_lambdaClauses <- mapM goClause c
return (ExpressionLambda Lambda {..})
ExpressionFunction (Function l r) -> do
l' <- goParam l
r' <- go r
Expand Down Expand Up @@ -201,7 +204,10 @@ mkPolyType = fmap PolyType . go
ExpressionIden IdenConstructor {} -> return t
ExpressionIden IdenAxiom {} -> return t
ExpressionIden IdenVar {} -> return t
ExpressionLambda (Lambda c) -> ExpressionLambda . Lambda <$> mapM goClause c
ExpressionLambda (Lambda c ty) -> do
let _lambdaType = ty >>= go
_lambdaClauses <- mapM goClause c
return (ExpressionLambda Lambda {..})
ExpressionSimpleLambda (SimpleLambda v ty b) -> do
b' <- go b
ty' <- go ty
Expand All @@ -219,7 +225,10 @@ instance HasExpressions LambdaClause where
leafExpressions f (LambdaClause ps b) = LambdaClause ps <$> leafExpressions f b

instance HasExpressions Lambda where
leafExpressions f = traverseOf lambdaClauses (traverse (leafExpressions f))
leafExpressions f l = do
_lambdaClauses <- traverse (leafExpressions f) (l ^. lambdaClauses)
_lambdaType <- traverse (leafExpressions f) (l ^. lambdaType)
pure Lambda {..}

instance HasExpressions Expression where
leafExpressions f e = case e of
Expand Down
6 changes: 4 additions & 2 deletions src/Juvix/Compiler/Internal/Language.hs
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,10 @@ data Case = Case

instance Hashable Case

newtype Lambda = Lambda
{ _lambdaClauses :: NonEmpty LambdaClause
data Lambda = Lambda
{ _lambdaClauses :: NonEmpty LambdaClause,
-- | The typechecker fills this field
_lambdaType :: Maybe Expression
}
deriving stock (Eq, Generic, Data)

Expand Down
7 changes: 4 additions & 3 deletions src/Juvix/Compiler/Internal/Pretty/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ instance PrettyCode LambdaClause where
instance PrettyCode Lambda where
ppCode Lambda {..} = do
lambdaClauses' <- ppPipeBlock _lambdaClauses
return $ kwLambda <+> lambdaClauses'
lambdaType' <- mapM ppCode _lambdaType
return $ kwLambda <+> (fmap (kwColon <+>) lambdaType') <?+> braces lambdaClauses'

instance PrettyCode a => PrettyCode (WithLoc a) where
ppCode = ppCode . (^. withLocParam)
Expand Down Expand Up @@ -187,7 +188,7 @@ instance PrettyCode FunctionDef where
clauses' <- mapM ppCode (f ^. funDefClauses)
return $
funDefName'
<+> kwColonColon
<+> kwColon
<+> funDefType'
<> line
<> vsep (toList clauses')
Expand All @@ -197,7 +198,7 @@ instance PrettyCode FunctionClause where
funName <- ppCode (c ^. clauseName)
clausePatterns' <- hsepMaybe <$> mapM ppCodeAtom (c ^. clausePatterns)
clauseBody' <- ppCode (c ^. clauseBody)
return $ funName <+?> clausePatterns' <+> kwAssign <+> clauseBody'
return $ nest 2 (funName <+?> clausePatterns' <+> kwAssign <+> clauseBody')

instance PrettyCode Backend where
ppCode = \case
Expand Down
5 changes: 4 additions & 1 deletion src/Juvix/Compiler/Internal/Translation/FromAbstract.hs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,10 @@ goType e = case e of
Abstract.ExpressionCase {} -> unsupported "case in types"

goLambda :: forall r. (Members '[NameIdGen] r) => Abstract.Lambda -> Sem r Lambda
goLambda (Abstract.Lambda cl') = Lambda <$> mapM goClause cl'
goLambda (Abstract.Lambda cl') = do
_lambdaClauses <- mapM goClause cl'
let _lambdaType :: Maybe Expression = Nothing
return Lambda {..}
where
goClause :: Abstract.LambdaClause -> Sem r LambdaClause
goClause (Abstract.LambdaClause ps b) = do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,10 @@ arityCase c = do
-- types, it is ok to (partially) infer the arity of the lambda from the clause
-- with the most patterns.
arityLambda :: Lambda -> Arity
arityLambda (Lambda cl) =
arityLambda l =
foldArity
UnfoldedArity
{ _ufoldArityParams = replicate (maximum1 (fmap numPatterns cl)) (ParamExplicit ArityUnknown),
{ _ufoldArityParams = replicate (maximum1 (fmap numPatterns (l ^. lambdaClauses))) (ParamExplicit ArityUnknown),
_ufoldArityRest = ArityRestUnknown
}
where
Expand Down Expand Up @@ -382,7 +382,10 @@ checkLambda ::
Arity ->
Lambda ->
Sem r Lambda
checkLambda ari (Lambda cl) = Lambda <$> mapM goClause cl
checkLambda ari l = do
let _lambdaType = l ^. lambdaType
_lambdaClauses <- mapM goClause (l ^. lambdaClauses)
return Lambda {..}
where
goClause :: LambdaClause -> Sem r LambdaClause
goClause (LambdaClause ps b) = do
Expand All @@ -409,7 +412,7 @@ checkLambda ari (Lambda cl) = Lambda <$> mapM goClause cl
-- TODO. think what to do in this case
return (pats, as)
(_ : _, []) -> case rest of
ArityRestUnit -> error ("too many patterns in lambda: " <> ppTrace (Lambda cl) <> "\n" <> prettyText ari)
ArityRestUnit -> error ("too many patterns in lambda: " <> ppTrace l <> "\n" <> prettyText ari)
ArityRestUnknown -> return (pats, [])

idenArity :: (Members '[Reader LocalVars, Reader InfoTable] r) => Iden -> Sem r Arity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ checkStrictlyPositiveOccurrences ty ctorName name recLimit ref =
helper inside lamBody

helperLambda :: Lambda -> Sem r ()
helperLambda (Lambda cl) = mapM_ goClause cl
helperLambda l = mapM_ goClause (l ^. lambdaClauses)
where
goClause :: LambdaClause -> Sem r ()
goClause (LambdaClause _ b) = helper inside b
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -573,11 +573,13 @@ inferExpression' hint e = case e of
}

goLambda :: Lambda -> Sem r TypedExpression
goLambda l@(Lambda cl) = do
goLambda l = do
ty <- case hint of
Just hi -> return hi
Nothing -> ExpressionHole <$> freshHole (getLoc l)
l' <- Lambda <$> mapM (goClause ty) cl
_lambdaClauses <- mapM (goClause ty) (l ^. lambdaClauses)
let _lambdaType = Just ty
l' = Lambda {..}
return
TypedExpression
{ _typedType = ty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,10 @@ strongNormalize' = go
return (LambdaClause p b')

goLambda :: Lambda -> Sem r Lambda
goLambda (Lambda cl) = Lambda <$> mapM goClause cl
goLambda l = do
_lambdaClauses <- mapM goClause (l ^. lambdaClauses)
_lambdaType <- mapM go (l ^. lambdaType)
return Lambda {..}

goSimpleLambda :: SimpleLambda -> Sem r SimpleLambda
goSimpleLambda (SimpleLambda lamVar lamTy lamBody) = do
Expand Down Expand Up @@ -342,9 +345,9 @@ re = reinterpret $ \case
_ -> id
bicheck (go l1 l2) (local' (go r1 r2))
| otherwise = err

-- NOTE type is ignored, I think it is ok
goLambda :: Lambda -> Lambda -> Sem r (Maybe MatchError)
goLambda (Lambda l1) (Lambda l2) = case zipExactMay (toList l1) (toList l2) of
goLambda (Lambda l1 _) (Lambda l2 _) = case zipExactMay (toList l1) (toList l2) of
Just z -> asum <$> mapM (uncurry goClause) z
_ -> err
where
Expand Down