You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a feeling this is not easily fixable, but it looks like it is impossible to pattern match on a type that is parameterized on a type constructor, when that type constructor is instantiated to a type alias or some sort of type level function.
Here's an example, from a stream processing library I am working on:
So, a Process can either halt, emit a value, or make an external request of its driver, where the external request is a call to evaluate the 'function' F. As a special case of this, we can constrain the requests to be of a particular type:
Now Process[One[Int]#f, String] is a stream transducer that can only request integer values from its sole input stream (and which emits Strings as its output type). The problem arises when I want to pattern match on a Process[One[A]#f, B]. I get 'constructor cannot be instantiated' errors:
objectFailing {
vala1=Await[One[Int]#f,Unit,Int,String](Get[Int](), (), (i:Int) =>Halt[One[Int]#f,String]())
valx:Process[One[Int]#f,String] = a1
valr= a1 match { caseAwait(f,x,r) => f }
}
This gives me:
<console>:32:error: constructor cannot be instantiated to expected type;
found : Await[F,X,Y,A]
required: Await[[X, Y]F1[Unit,Int],Unit,Int,String]
valr= a1 match { caseAwait(f,x,r) => f }
^
<console>:32:error: not found: value f
valr= a1 match { caseAwait(f,x,r) => f }
I'm guessing this is just the usual limitation that a type constructor will never be inferred as a type level function, however it means that I can't meaningfully pattern match on Process, like if I want to implement piping the output of one process to another:
I don't think your workaround helps here, since now the Process types are completely unrelated to each other and can't be combined. :( One of the points of this library I am writing (it is based roughly on Ed's machines library and the port to Scala is that we can mix and match Processes with different capabilities (represented by their F argument).
The workaround I settled on was something like this:
caseclassTwo[A,B]() { // a two input Processtypef[x,y] { defget:Either[A=:= y, B=:= y] }
caseobjectLextends f[Unit,A] { defget=Left(implicitly) }
caseobjectRextends f[Unit,B] { defget=Right(implicitly) }
}
I then use Process[Two[A,B]#f,C] to represent a Process that accepts two inputs, and now f is an actual type, not just a type alias, so I can go back to pattern matching on Await. I can't pattern match on L and R (since TwoA,B.L != TwoA,B.L - they belong to completely separate types), but even if I could Scala is missing the GADT support that would refine the types properly there anyway. Instead I pattern match on the result of calling get, which contains an equality witness on either side that also lets me refine the types correctly. Somewhat annoying to use but not too horrible so far...
I have a feeling this is not easily fixable, but it looks like it is impossible to pattern match on a type that is parameterized on a type constructor, when that type constructor is instantiated to a type alias or some sort of type level function.
Here's an example, from a stream processing library I am working on:
So, a Process can either halt, emit a value, or make an external request of its driver, where the external request is a call to evaluate the 'function' F. As a special case of this, we can constrain the requests to be of a particular type:
Now Process[One[Int]#f, String] is a stream transducer that can only request integer values from its sole input stream (and which emits Strings as its output type). The problem arises when I want to pattern match on a Process[One[A]#f, B]. I get 'constructor cannot be instantiated' errors:
This gives me:
I'm guessing this is just the usual limitation that a type constructor will never be inferred as a type level function, however it means that I can't meaningfully pattern match on Process, like if I want to implement piping the output of one process to another:
Is the only workaround here to define my own custom extractors?
The text was updated successfully, but these errors were encountered: