package nl.utwente.viskell.haskell.type;
import nl.utwente.viskell.haskell.expr.Apply;
import nl.utwente.viskell.haskell.expr.Value;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class BubbleTest {
@Test
public void testBubbleUnit() throws Exception {
TypeScope scope = new TypeScope();
TypeVar a = scope.getVar("a");
TypeVar z = scope.getVar("z");
TypeCon u = Type.con("Unit");
Type aFunc = Type.fun(a, a);
Type bFunc = Type.fun(u, u);
// "(unit (id undefined))"
Apply apply = new Apply(new Value(bFunc, "unit"), new Apply(new Value(aFunc, "id"), new Value(z, "undefined")));
// Do type inference.
Type t = apply.inferType();
// Inferred type of the whole expression is 'Unit'.
assertEquals("Unit", t.prettyPrint());
// Inferred type of "(unit (id undefined))" is 'Unit'.
assertEquals("Unit", u.prettyPrint());
// Inferred type of "(id undefined)" is 'Unit'.
assertEquals("Unit", a.prettyPrint());
// Inferred type of (this instance of the 'value') "undefined" is 'Unit'.
assertEquals("Unit", z.prettyPrint());
}
@Test
public void testBubbleAddition() throws Exception {
TypeScope scope = new TypeScope();
TypeVar a = scope.getVar("a");
TypeVar b = scope.getVar("b");
TypeVar c = scope.getVar("c");
TypeCon floatT = Type.con("Float");
Apply apply = new Apply(
new Apply(
new Value(Type.fun(floatT, floatT, floatT), "+"),
new Apply(
new Value(Type.fun(a, a), "id"),
new Value(b, "undefined")
)
),
new Value(c, "undefined")
);
assertEquals("(((+) ((id) (undefined))) (undefined))", apply.toHaskell());
Type t = apply.inferType();
assertEquals("Float", t.prettyPrint());
assertEquals("Float", a.prettyPrint());
assertEquals("Float", b.prettyPrint());
assertEquals("Float", c.prettyPrint());
}
@Test
public void testBubbleEquals() throws Exception {
TypeScope scope = new TypeScope();
TypeCon Float = Type.con("Float");
TypeClass Num = new TypeClass("Num", Float);
TypeVar a = scope.getVarTC("a", Num);
TypeVar b = scope.getVar("b");
Apply apply = new Apply(
new Apply(
new Value(Type.fun(a, a, a), "=="),
new Value(Float, "5.0")
),
new Value(b, "undefined")
);
assertEquals("(((==) (5.0)) (undefined))", apply.toHaskell());
Type t = apply.inferType();
assertEquals("Float", t.prettyPrint());
assertEquals("Float", a.prettyPrint());
assertEquals("Float", b.prettyPrint());
}
}