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

Inconsistency in flexibility of patterns and nested patterns #10

Open
mpickering opened this issue Jun 6, 2017 · 0 comments
Open

Inconsistency in flexibility of patterns and nested patterns #10

mpickering opened this issue Jun 6, 2017 · 0 comments

Comments

@mpickering
Copy link

In an email with Craig, he pointed out a workaround to a problem I had been having.
Playing around with his workaround highlighted an inconsistency with how patterns are type checked.

In handleModifyPlayOrder, I can pattern match on MkEC and then use the effect polymorphic computation in an environment which has access to the State ability.

If I try to write a top level definition, not a handler, h, which does the same thing but does not handle an effect then the use of f is rejected.

on : X -> {X -> Y} -> Y
on x g = g x

interface ModifyOrder [E] = modifyOrder : EndoComp (List X) -> Unit

data EndoComp Y = MkEC {Y -> Y}

---
rotate : List X -> List X
rotate x = x

data S = S (List P)

interface State = get : S | put : S -> Unit

handleModifyPlayOrder : <ModifyOrder>X -> [State]X
handleModifyPlayOrder x = x
handleModifyPlayOrder <modifyOrder (MkEC f) -> k> =
  on get! { (S po) -> put (S (f po)); handleModifyPlayOrder (k unit) }

-- This doesn't type check
--h : EndoComp (List X) -> [State]Unit
--h (MkEC f) =
--  on get! { (S po) -> put (S (f po)) }

main : { [Console]Unit }
main! = unit

= Analysis

There seems to be an inconsistency about where makeFlexible is called.

In the first definition, the type checking first enters checkPat and then the case for MkCmdPat. Then crucially,
in the Just branch, makeFlexible is mapped over the types of the patterns. checkVPat is then called on each of the patterns with these flexible types.

In the second case, checkPat is called directly from checkCls which doesn't call makeFlexible on the result type which means the rigid type variable (X$r10) causes unification to fail.

This means that the arguments to checkVPat look like this, notice the subtle difference of MkRVar vs MkFVar.

For the handler:
Pattern Type: MkDTTy "EndoComp" [VArg (MkDTTy "List" [VArg (MkFTVar "X$f1")])
Args Type: EArg (MkAb (MkAbFVar "\163$f2") (fromList []))],[VArg (MkFTVar "Y$f3"),EArg (MkAb (MkAbFVar "\163$f4") (fromList []))])

For h:
Pattern Type: MkDTTy "EndoComp" [VArg (MkDTTy "List" [VArg (MkRTVar "X$r10")])
Args Type: EArg (MkAb (MkAbRVar "\163$r7") (fromList []))],[VArg (MkFTVar "Y$f0"),EArg (MkAb (MkAbFVar "\163$f1") (fromList []))])
@mpickering mpickering changed the title Inconsistency in how type arguments are made flexible in pattern matches Inconsistency in flexibility of patterns and nested patterns Jun 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant