diff options
-rw-r--r-- | src/type/check.rs | 8 | ||||
-rw-r--r-- | src/type/conversion.rs | 15 |
2 files changed, 22 insertions, 1 deletions
diff --git a/src/type/check.rs b/src/type/check.rs index 5ccd0e7..bb88efb 100644 --- a/src/type/check.rs +++ b/src/type/check.rs @@ -510,6 +510,14 @@ impl Type { Ok(r1) }, + (SumType(a1, a2), SumType(b1, b2)) => { + let mut r1 = a1.infer_generics_ctx(b1, ctx.clone())?; + let r2 = a2.infer_generics_ctx(b2, ctx.clone())?; + r1.extend_from_slice(&r2); + r1.extend_from_slice(&ctx); + Ok(r1) + }, + (List(v1), List(v2)) => { let mut res = ctx.clone(); for (t1, t2) in v1.into_iter().zip(v2.into_iter()) { diff --git a/src/type/conversion.rs b/src/type/conversion.rs index ab858e6..54fc59d 100644 --- a/src/type/conversion.rs +++ b/src/type/conversion.rs @@ -11,7 +11,7 @@ impl Type { /// 0. self == other => self /// 1. (T T ... T T) -> (T ...) /// 2. self = concrete and other = variable type => self, - /// 3. arrow types and lists are mapped + /// 3. arrow types and lists and sums are mapped /// 4. makes [self] self if self == other pub fn convert(self, other: &Type) -> Result<Type, ()> { let (ty, ctx) = self.convert_ctx(other)?; @@ -62,6 +62,14 @@ impl Type { Ok((arr(t1, t2), ctx)) }, + (SumType(a1, a2), SumType(b1, b2)) => { + let (t1, newctx) = a1.convert_ctx(b1)?; + ctx.extend(newctx); + let (t2, newctx) = a2.convert_ctx(b2)?; + ctx.extend(newctx); + Ok((sumtype(t1, t2), ctx)) + }, + (List(v), VecOf(ty)) => match v.get(0) { Some(t) => { let (convt, newctx) = t.clone().convert_ctx(ty)?; @@ -163,6 +171,11 @@ mod tests { .convert(&arr(vt("T"), vt("T"))), Ok(arr(arr(vecof(Integer), Integer), arr(vecof(Integer), Integer))) ); + assert_eq!( + sumtype(sumtype(vecof(Integer), Integer), sumtype(vecof(Integer), Integer)) + .convert(&sumtype(vt("T"), vt("T"))), + Ok(sumtype(sumtype(vecof(Integer), Integer), sumtype(vecof(Integer), Integer))) + ); assert!( List(vec![Integer, Boolean]) |