parsing and desugaring of do blocks. (Some inference issues remain.)
This commit is contained in:
@@ -3,6 +3,7 @@ module TypeClass
|
|||||||
data Monad : (U -> U) -> U where
|
data Monad : (U -> U) -> U where
|
||||||
MkMonad : { M : U -> U } ->
|
MkMonad : { M : U -> U } ->
|
||||||
(bind : {A B : U} -> (M A) -> (A -> M B) -> M B) ->
|
(bind : {A B : U} -> (M A) -> (A -> M B) -> M B) ->
|
||||||
|
(pure : {A : U} -> A -> M A) ->
|
||||||
Monad M
|
Monad M
|
||||||
|
|
||||||
data Maybe : U -> U where
|
data Maybe : U -> U where
|
||||||
@@ -18,21 +19,36 @@ bindEither (Left a) amb = Left a
|
|||||||
bindEither (Right b) amb = amb b
|
bindEither (Right b) amb = amb b
|
||||||
|
|
||||||
EitherMonad : {A : U} -> Monad (Either A)
|
EitherMonad : {A : U} -> Monad (Either A)
|
||||||
EitherMonad = MkMonad {Either A} bindEither
|
EitherMonad = MkMonad {Either A} bindEither Right
|
||||||
|
|
||||||
bindMaybe : {A B : U} -> Maybe A -> (A -> Maybe B) -> Maybe B
|
bindMaybe : {A B : U} -> Maybe A -> (A -> Maybe B) -> Maybe B
|
||||||
bindMaybe Nothing amb = Nothing
|
bindMaybe Nothing amb = Nothing
|
||||||
bindMaybe (Just a) amb = amb a
|
bindMaybe (Just a) amb = amb a
|
||||||
|
|
||||||
MaybeMonad : Monad Maybe
|
MaybeMonad : Monad Maybe
|
||||||
MaybeMonad = MkMonad bindMaybe
|
MaybeMonad = MkMonad bindMaybe Just
|
||||||
|
|
||||||
_>>=_ : {a b : U} -> {m : U -> U} -> {{x : Monad m}} -> (m a) -> (a -> m b) -> m b
|
_>>=_ : {a b : U} -> {m : U -> U} -> {{x : Monad m}} -> (m a) -> (a -> m b) -> m b
|
||||||
_>>=_ {a} {b} {m} {{MkMonad bind'}} ma amb = bind' {a} {b} ma amb
|
_>>=_ {a} {b} {m} {{MkMonad bind' _}} ma amb = bind' {a} {b} ma amb
|
||||||
|
|
||||||
infixl 1 _>>=_
|
pure : {a : U} {m : U -> U} {{_ : Monad m}} -> a -> m a
|
||||||
|
pure {_} {_} {{MkMonad _ pure'}} a = pure' a
|
||||||
|
|
||||||
|
infixl 1 _>>=_ _>>_
|
||||||
|
|
||||||
|
_>>_ : {a b : U} -> {m : U -> U} -> {{x : Monad m}} -> m a -> m b -> m b
|
||||||
|
|
||||||
ptype Int
|
ptype Int
|
||||||
|
|
||||||
|
test : Maybe Int
|
||||||
|
test = pure 10
|
||||||
|
|
||||||
foo : Int -> Maybe Int
|
foo : Int -> Maybe Int
|
||||||
foo x = (Just x) >>= (\ x => Just 10)
|
foo x = Just 42 >> Just x >>= (\ x => pure {_} {Maybe} 10)
|
||||||
|
|
||||||
|
bar : Int -> Maybe Int
|
||||||
|
bar x = do
|
||||||
|
let y = x
|
||||||
|
z <- Just x
|
||||||
|
-- This is not sorting out the Maybe...
|
||||||
|
pure {_} {_} z
|
||||||
|
|||||||
@@ -257,10 +257,14 @@ parameters (ctx: Context)
|
|||||||
debug "env \{show ctx.env}"
|
debug "env \{show ctx.env}"
|
||||||
debug "types \{show $ ctx.types}"
|
debug "types \{show $ ctx.types}"
|
||||||
case (t',u') of
|
case (t',u') of
|
||||||
|
|
||||||
|
-- flex/flex
|
||||||
(VMeta fc k sp, VMeta fc' k' sp' ) =>
|
(VMeta fc k sp, VMeta fc' k' sp' ) =>
|
||||||
if k == k' then unifySpine l (k == k') sp sp'
|
if k == k' then unifySpine l (k == k') sp sp'
|
||||||
-- TODO, might want to try the other way, too.
|
-- TODO, might want to try the other way, too.
|
||||||
else solve l k sp (VMeta fc' k' sp') >> pure neutral
|
else if length sp < length sp'
|
||||||
|
then solve l k' sp' (VMeta fc k sp) >> pure neutral
|
||||||
|
else solve l k sp (VMeta fc' k' sp') >> pure neutral
|
||||||
(t, VMeta fc' i' sp') => solve l i' sp' t >> pure neutral
|
(t, VMeta fc' i' sp') => solve l i' sp' t >> pure neutral
|
||||||
(VMeta fc i sp, t' ) => solve l i sp t' >> pure neutral
|
(VMeta fc i sp, t' ) => solve l i sp t' >> pure neutral
|
||||||
(VPi fc _ _ a b, VPi fc' _ _ a' b') => [| unify l a a' <+> unify (S l) !(b $$ VVar emptyFC l [<]) !(b' $$ VVar emptyFC l [<]) |]
|
(VPi fc _ _ a b, VPi fc' _ _ a' b') => [| unify l a a' <+> unify (S l) !(b $$ VVar emptyFC l [<]) !(b' $$ VVar emptyFC l [<]) |]
|
||||||
@@ -612,7 +616,8 @@ buildCase ctx prob scnm scty (dcName, arity, ty) = do
|
|||||||
makeConstr [] (pat :: pats) = ?extra_patterns
|
makeConstr [] (pat :: pats) = ?extra_patterns
|
||||||
makeConstr ((MkBind nm Implicit x) :: xs) [] = (nm, PatWild emptyFC Implicit) :: makeConstr xs []
|
makeConstr ((MkBind nm Implicit x) :: xs) [] = (nm, PatWild emptyFC Implicit) :: makeConstr xs []
|
||||||
makeConstr ((MkBind nm Auto x) :: xs) [] = (nm, PatWild emptyFC Auto) :: makeConstr xs []
|
makeConstr ((MkBind nm Auto x) :: xs) [] = (nm, PatWild emptyFC Auto) :: makeConstr xs []
|
||||||
makeConstr ((MkBind nm Explicit x) :: xs) [] = ?extra_binders_2
|
-- FIXME need a proper error, but requires wiring M three levels down
|
||||||
|
makeConstr ((MkBind nm Explicit x) :: xs) [] = ?insufficient_patterns
|
||||||
makeConstr ((MkBind nm Explicit x) :: xs) (pat :: pats) =
|
makeConstr ((MkBind nm Explicit x) :: xs) (pat :: pats) =
|
||||||
if getIcit pat == Explicit
|
if getIcit pat == Explicit
|
||||||
then (nm, pat) :: makeConstr xs pats
|
then (nm, pat) :: makeConstr xs pats
|
||||||
@@ -822,7 +827,18 @@ showDef : Context -> List String -> Nat -> Val -> M String
|
|||||||
showDef ctx names n v@(VVar _ n' [<]) = if n == n' then pure "" else pure "= \{pprint names !(quote ctx.lvl v)}"
|
showDef ctx names n v@(VVar _ n' [<]) = if n == n' then pure "" else pure "= \{pprint names !(quote ctx.lvl v)}"
|
||||||
showDef ctx names n v = pure "= \{pprint names !(quote ctx.lvl v)}"
|
showDef ctx names n v = pure "= \{pprint names !(quote ctx.lvl v)}"
|
||||||
|
|
||||||
|
|
||||||
|
undo : List DoStmt -> M Raw
|
||||||
|
undo [] = error emptyFC "do block must end in expression"
|
||||||
|
undo ((DoExpr fc tm) :: Nil) = pure tm
|
||||||
|
-- TODO decide if we want to use >> or just >>=
|
||||||
|
undo ((DoExpr fc tm) :: xs) = pure $ RApp fc (RApp fc (RVar fc "_>>=_") tm Explicit) (RLam fc "_" Explicit !(undo xs)) Explicit
|
||||||
|
-- undo ((DoExpr fc tm) :: xs) = pure $ RApp fc (RApp fc (RVar fc "_>>_") tm Explicit) !(undo xs) Explicit
|
||||||
|
undo ((DoLet fc nm tm) :: xs) = RLet fc nm (RImplicit fc) tm <$> undo xs
|
||||||
|
undo ((DoArrow fc nm tm) :: xs) = pure $ RApp fc (RApp fc (RVar fc "_>>=_") tm Explicit) (RLam fc nm Explicit !(undo xs)) Explicit
|
||||||
|
|
||||||
check ctx tm ty = case (tm, !(forceType ty)) of
|
check ctx tm ty = case (tm, !(forceType ty)) of
|
||||||
|
(RDo fc stmts, ty) => check ctx !(undo stmts) ty
|
||||||
(RCase fc rsc alts, ty) => do
|
(RCase fc rsc alts, ty) => do
|
||||||
(sc, scty) <- infer ctx rsc
|
(sc, scty) <- infer ctx rsc
|
||||||
scty <- forceMeta scty
|
scty <- forceMeta scty
|
||||||
@@ -989,7 +1005,3 @@ infer ctx (RLit fc (LString str)) = pure (Lit fc (LString str), !(primType fc "S
|
|||||||
infer ctx (RLit fc (LInt i)) = pure (Lit fc (LInt i), !(primType fc "Int"))
|
infer ctx (RLit fc (LInt i)) = pure (Lit fc (LInt i), !(primType fc "Int"))
|
||||||
|
|
||||||
infer ctx tm = error (getFC tm) "Implement infer \{show tm}"
|
infer ctx tm = error (getFC tm) "Implement infer \{show tm}"
|
||||||
|
|
||||||
-- The idea here is to insert a hole for a parse error
|
|
||||||
-- but the parser doesn't emit this yet.
|
|
||||||
-- infer ctx (RParseError str) = ?todo_insert_meta
|
|
||||||
|
|||||||
@@ -203,10 +203,28 @@ caseExpr = do
|
|||||||
alts <- startBlock $ someSame $ caseAlt
|
alts <- startBlock $ someSame $ caseAlt
|
||||||
pure $ RCase fc sc alts
|
pure $ RCase fc sc alts
|
||||||
|
|
||||||
|
doArrow : Parser DoStmt
|
||||||
|
doArrow = do
|
||||||
|
fc <- getPos
|
||||||
|
name <- try $ ident <* keyword "<-"
|
||||||
|
expr <- term
|
||||||
|
pure $ DoArrow fc name expr
|
||||||
|
|
||||||
|
doStmt : Parser DoStmt
|
||||||
|
doStmt
|
||||||
|
= DoArrow <$> getPos <*> (try $ ident <* keyword "<-") <*> term
|
||||||
|
<|> DoLet <$> getPos <* keyword "let" <*> ident <* keyword "=" <*> term
|
||||||
|
<|> DoExpr <$> getPos <*> term
|
||||||
|
|
||||||
|
doExpr : Parser Raw
|
||||||
|
doExpr = RDo <$> getPos <* keyword "do" <*> (startBlock $ someSame doStmt)
|
||||||
|
|
||||||
|
|
||||||
-- This hits an idris codegen bug if parseOp is last and Lazy
|
-- This hits an idris codegen bug if parseOp is last and Lazy
|
||||||
term = caseExpr
|
term = caseExpr
|
||||||
<|> letExpr
|
<|> letExpr
|
||||||
<|> lamExpr
|
<|> lamExpr
|
||||||
|
<|> doExpr
|
||||||
<|> parseOp
|
<|> parseOp
|
||||||
|
|
||||||
varname : Parser String
|
varname : Parser String
|
||||||
|
|||||||
@@ -59,6 +59,12 @@ record Clause where
|
|||||||
public export
|
public export
|
||||||
data RCaseAlt = MkAlt Raw Raw
|
data RCaseAlt = MkAlt Raw Raw
|
||||||
|
|
||||||
|
public export
|
||||||
|
data DoStmt : Type where
|
||||||
|
DoExpr : (fc : FC) -> Raw -> DoStmt
|
||||||
|
DoLet : (fc : FC) -> String -> Raw -> DoStmt
|
||||||
|
DoArrow : (fc: FC) -> String -> Raw -> DoStmt
|
||||||
|
|
||||||
data Raw : Type where
|
data Raw : Type where
|
||||||
RVar : (fc : FC) -> (nm : Name) -> Raw
|
RVar : (fc : FC) -> (nm : Name) -> Raw
|
||||||
RLam : (fc : FC) -> (nm : String) -> (icit : Icit) -> (ty : Raw) -> Raw
|
RLam : (fc : FC) -> (nm : String) -> (icit : Icit) -> (ty : Raw) -> Raw
|
||||||
@@ -71,8 +77,8 @@ data Raw : Type where
|
|||||||
RCase : (fc : FC) -> (scrut : Raw) -> (alts : List RCaseAlt) -> Raw
|
RCase : (fc : FC) -> (scrut : Raw) -> (alts : List RCaseAlt) -> Raw
|
||||||
RImplicit : (fc : FC) -> Raw
|
RImplicit : (fc : FC) -> Raw
|
||||||
RHole : (fc : FC) -> Raw
|
RHole : (fc : FC) -> Raw
|
||||||
-- not used, but intended to allow error recovery
|
RDo : (fc : FC) -> List DoStmt -> Raw
|
||||||
RParseError : (fc : FC) -> String -> Raw
|
|
||||||
|
|
||||||
%name Raw tm
|
%name Raw tm
|
||||||
|
|
||||||
@@ -89,7 +95,7 @@ HasFC Raw where
|
|||||||
getFC (RCase fc scrut alts) = fc
|
getFC (RCase fc scrut alts) = fc
|
||||||
getFC (RImplicit fc) = fc
|
getFC (RImplicit fc) = fc
|
||||||
getFC (RHole fc) = fc
|
getFC (RHole fc) = fc
|
||||||
getFC (RParseError fc str) = fc
|
getFC (RDo fc stmts) = fc
|
||||||
-- derive some stuff - I'd like json, eq, show, ...
|
-- derive some stuff - I'd like json, eq, show, ...
|
||||||
|
|
||||||
|
|
||||||
@@ -181,7 +187,7 @@ Show Raw where
|
|||||||
show (RApp _ x y z) = foo [ "App", show x, show y, show z]
|
show (RApp _ x y z) = foo [ "App", show x, show y, show z]
|
||||||
show (RLam _ x i y) = foo [ "Lam", show x, show i, show y]
|
show (RLam _ x i y) = foo [ "Lam", show x, show i, show y]
|
||||||
show (RCase _ x xs) = foo [ "Case", show x, show xs]
|
show (RCase _ x xs) = foo [ "Case", show x, show xs]
|
||||||
show (RParseError _ str) = foo [ "ParseError", "str"]
|
show (RDo _ stmts) = foo [ "DO", "FIXME"]
|
||||||
show (RU _) = "U"
|
show (RU _) = "U"
|
||||||
|
|
||||||
export
|
export
|
||||||
@@ -233,7 +239,7 @@ Pretty Raw where
|
|||||||
asDoc p (RCase _ x xs) = text "TODO - RCase"
|
asDoc p (RCase _ x xs) = text "TODO - RCase"
|
||||||
asDoc p (RImplicit _) = text "_"
|
asDoc p (RImplicit _) = text "_"
|
||||||
asDoc p (RHole _) = text "?"
|
asDoc p (RHole _) = text "?"
|
||||||
asDoc p (RParseError _ str) = text "ParseError \{str}"
|
asDoc p (RDo _ stmts) = text "TODO - RDo"
|
||||||
|
|
||||||
export
|
export
|
||||||
Pretty Module where
|
Pretty Module where
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import Text.Lexer.Tokenizer
|
|||||||
import Lib.Token
|
import Lib.Token
|
||||||
|
|
||||||
keywords : List String
|
keywords : List String
|
||||||
keywords = ["let", "in", "where", "case", "of", "data", "U",
|
keywords = ["let", "in", "where", "case", "of", "data", "U", "do",
|
||||||
"ptype", "pfunc", "module", "infixl", "infixr", "infix"]
|
"ptype", "pfunc", "module", "infixl", "infixr", "infix"]
|
||||||
|
|
||||||
specialOps : List String
|
specialOps : List String
|
||||||
specialOps = ["->", ":", "=>", ":=", "="]
|
specialOps = ["->", ":", "=>", ":=", "=", "<-"]
|
||||||
|
|
||||||
checkKW : String -> Token Kind
|
checkKW : String -> Token Kind
|
||||||
checkKW s = if elem s keywords then Tok Keyword s else Tok Ident s
|
checkKW s = if elem s keywords then Tok Keyword s else Tok Ident s
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ module TypeClass
|
|||||||
data Monad : (U -> U) -> U where
|
data Monad : (U -> U) -> U where
|
||||||
MkMonad : { M : U -> U } ->
|
MkMonad : { M : U -> U } ->
|
||||||
(bind : {A B : U} -> (M A) -> (A -> M B) -> M B) ->
|
(bind : {A B : U} -> (M A) -> (A -> M B) -> M B) ->
|
||||||
|
(pure : {A : U} -> A -> M A) ->
|
||||||
Monad M
|
Monad M
|
||||||
|
|
||||||
data Maybe : U -> U where
|
data Maybe : U -> U where
|
||||||
@@ -18,21 +19,36 @@ bindEither (Left a) amb = Left a
|
|||||||
bindEither (Right b) amb = amb b
|
bindEither (Right b) amb = amb b
|
||||||
|
|
||||||
EitherMonad : {A : U} -> Monad (Either A)
|
EitherMonad : {A : U} -> Monad (Either A)
|
||||||
EitherMonad = MkMonad {Either A} bindEither
|
EitherMonad = MkMonad {Either A} bindEither Right
|
||||||
|
|
||||||
bindMaybe : {A B : U} -> Maybe A -> (A -> Maybe B) -> Maybe B
|
bindMaybe : {A B : U} -> Maybe A -> (A -> Maybe B) -> Maybe B
|
||||||
bindMaybe Nothing amb = Nothing
|
bindMaybe Nothing amb = Nothing
|
||||||
bindMaybe (Just a) amb = amb a
|
bindMaybe (Just a) amb = amb a
|
||||||
|
|
||||||
MaybeMonad : Monad Maybe
|
MaybeMonad : Monad Maybe
|
||||||
MaybeMonad = MkMonad bindMaybe
|
MaybeMonad = MkMonad bindMaybe Just
|
||||||
|
|
||||||
_>>=_ : {a b : U} -> {m : U -> U} -> {{x : Monad m}} -> (m a) -> (a -> m b) -> m b
|
_>>=_ : {a b : U} -> {m : U -> U} -> {{x : Monad m}} -> (m a) -> (a -> m b) -> m b
|
||||||
_>>=_ {a} {b} {m} {{MkMonad bind'}} ma amb = bind' {a} {b} ma amb
|
_>>=_ {a} {b} {m} {{MkMonad bind' _}} ma amb = bind' {a} {b} ma amb
|
||||||
|
|
||||||
infixl 1 _>>=_
|
pure : {a : U} {m : U -> U} {{_ : Monad m}} -> a -> m a
|
||||||
|
pure {_} {_} {{MkMonad _ pure'}} a = pure' a
|
||||||
|
|
||||||
|
infixl 1 _>>=_ _>>_
|
||||||
|
|
||||||
|
_>>_ : {a b : U} -> {m : U -> U} -> {{x : Monad m}} -> m a -> m b -> m b
|
||||||
|
|
||||||
ptype Int
|
ptype Int
|
||||||
|
|
||||||
|
test : Maybe Int
|
||||||
|
test = pure 10
|
||||||
|
|
||||||
foo : Int -> Maybe Int
|
foo : Int -> Maybe Int
|
||||||
foo x = (Just x) >>= (\ x => Just 10)
|
foo x = Just 42 >> Just x >>= (\ x => pure {_} {Maybe} 10)
|
||||||
|
|
||||||
|
bar : Int -> Maybe Int
|
||||||
|
bar x = do
|
||||||
|
let y = x
|
||||||
|
z <- Just x
|
||||||
|
-- NOW each of these implicits is a different error, fix them
|
||||||
|
pure {_} {Maybe} z
|
||||||
|
|||||||
Reference in New Issue
Block a user