Safe Haskell | None |
---|---|
Language | Haskell2010 |
Documentation
test :: Exp Source -> String Source
Mutable variable being assigned incompatible types:
>>>
let p = emptySource
>>>
let fun args = EAbs p ("this":args)
>>>
let var = EVar p
>>>
let let' = ELet p
>>>
let tuple = ETuple p
>>>
let lit = ELit p
>>>
let app a b = EApp p a [lit LitUndefined, b]
>>>
let assign = EAssign p
>>>
let array = EArray p
x is known to have type forall a. a -> a, and to have been used in a context requiring bool -> bool (e.g. `x True`)
we now try to assign x := y -> 2
This should fail because it "collapses" x to be Number -> Number which is not compatible with bool -> bool
>>>
test $ let' "x" (fun ["z"] (var "z")) (let' "y" (tuple [app (var "x") (lit (LitNumber 2)), app (var "x") (lit (LitBoolean True))]) (assign "x" (fun ["y"] (lit (LitNumber 0))) (tuple [var "x", var "y"])))
":1:1*: Error: Could not unify: Number with Boolean"
The following should succeed because x is immutable and thus polymorphic:
>>>
test $ let' "x" (fun ["z"] (var "z")) (let' "y" (tuple [app (var "x") (lit (LitNumber 2)), app (var "x") (lit (LitBoolean True))]) (tuple [var "x", var "y"]))
"(c.(d -> d), (Number, Boolean))"
The following should fail because x is mutable and therefore a monotype:
>>>
test $ let' "x" (fun ["z"] (var "z")) (let' "y" (tuple [app (var "x") (lit (LitNumber 2)), app (var "x") (lit (LitBoolean True))]) (assign "x" (fun ["z1"] (var "z1")) (tuple [var "x", var "y"])))
":1:1*: Error: Could not unify: Number with Boolean"
The following should also succeed because "x" is only ever used like this: (x True). The second assignment to x is: x := z1 -> False, which is specific but matches the usage. Note that x's type is collapsed to: Boolean -> Boolean.
>>>
test $ let' "x" (fun ["z"] (var "z")) (let' "y" (app (var "x") (lit (LitBoolean True))) (assign "x" (fun ["z1"] (lit (LitBoolean False))) (tuple [var "x", var "y"])))
"((Boolean -> Boolean), Boolean)"
| Tests a setter for x being called with something more specific than x's original definition: >>> :{ >>> test $ let' >>> "x" (fun ["a"] (var "a")) >>> (let' "setX" >>> (fun ["v"] >>> (let' >>> "_" (assign "x" (var "v") (var "x")) (lit (LitBoolean False)))) >>> (let' >>> "_" (app (var "setX") (fun ["a"] (lit (LitString "a")))) >>> (app (var "x") (lit (LitBoolean True))))) >>> :} ":1:1*: Error: Could not unify: String with Boolean"
>>>
test $ tuple [lit (LitBoolean True), lit (LitNumber 2)]
"(Boolean, Number)"
>>>
test $ let' "id" (fun ["x"] (var "x")) (assign "id" (fun ["y"] (var "y")) (var "id"))
"a.(b -> b)"
>>>
test $ let' "id" (fun ["x"] (var "x")) (assign "id" (lit (LitBoolean True)) (var "id"))
":1:1*: Error: Could not unify: a.(b -> b) with Boolean"
>>>
test $ let' "x" (lit (LitBoolean True)) (assign "x" (lit (LitBoolean False)) (var "x"))
"Boolean"
>>>
test $ let' "x" (lit (LitBoolean True)) (assign "x" (lit (LitNumber 3)) (var "x"))
":1:1*: Error: Could not unify: Boolean with Number"
>>>
test $ let' "x" (array [lit (LitBoolean True)]) (var "x")
"[Boolean]"
>>>
test $ let' "x" (array [lit $ LitBoolean True, lit $ LitBoolean False]) (var "x")
"[Boolean]"
>>>
test $ let' "x" (array []) (assign "x" (array []) (var "x"))
"[a]"
>>>
test $ let' "x" (array [lit $ LitBoolean True, lit $ LitNumber 2]) (var "x")
":1:1*: Error: Could not unify: Number with Boolean"
>>>
test $ let' "id" (fun ["x"] (let' "y" (var "x") (var "y"))) (app (var "id") (var "id"))
"c.(d -> d)"
>>>
test $ let' "id" (fun ["x"] (let' "y" (var "x") (var "y"))) (app (app (var "id") (var "id")) (lit (LitNumber 2)))
"Number"
>>>
test $ let' "id" (fun ["x"] (app (var "x") (var "x"))) (var "id")
":1:1*: Error: Occurs check failed: a in (a -> b)"
>>>
test $ fun ["m"] (let' "y" (var "m") (let' "x" (app (var "y") (lit (LitBoolean True))) (var "x")))
"a.((Boolean -> b) -> b)"
>>>
test $ app (lit (LitNumber 2)) (lit (LitNumber 2))
":1:1*: Error: Could not unify: Number with (Number -> a)"
EAssign tests >>> test $ let' "x" (fun ["y"] (lit (LitNumber 0))) (assign "x" (fun ["y"] (var "y")) (var "x")) "a.(Number -> Number)"
>>>
test $ let' "x" (fun ["y"] (var "y")) (assign "x" (fun ["y"] (lit (LitNumber 0))) (var "x"))
"a.(Number -> Number)"
>>>
test $ let' "x" (fun ["y"] (var "y")) (tuple [app (var "x") (lit (LitNumber 2)), app (var "x") (lit (LitBoolean True))])
"(Number, Boolean)"
>>>
test $ let' "x" (fun ["y"] (var "y")) (app (var "x") (var "x"))
"c.(d -> d)"
>>>
test $ let' "x" (fun ["a"] (var "a")) (let' "getX" (fun ["v"] (var "x")) (let' "setX" (fun ["v"] (let' "_" (assign "x" (var "v") (var "x")) (lit (LitBoolean True)))) (let' "_" (app (var "setX") (fun ["a"] (lit (LitString "a")))) (var "getX"))))
"e.(f -> d.(String -> String))"
Pretty Bool | |
Pretty SourcePos | |
Pretty InferState | |
Pretty NameSource | |
Pretty VarId | |
Pretty ClassName | |
Pretty TypeError | |
Pretty Source | |
Pretty Type | |
Pretty RowTVar | |
Pretty TConsName | |
Pretty TypeId | |
Pretty TBody | |
Pretty TVarName |
|
Pretty LitVal | |
Pretty EVarName | |
Pretty GenInfo | |
Pretty [String] | |
(Pretty a, Pretty b) => Pretty [(a, b)] | |
Pretty t => Pretty [TPred t] | |
Pretty [Type] | |
Pretty a => Pretty (Maybe a) | |
Pretty k => Pretty (Set k) | |
(Ord t, VarNames t, Pretty t) => Pretty (TScheme t) | |
(VarNames t, Pretty t) => Pretty (TQual t) | |
Pretty t => Pretty (TPred t) | |
(Ord t, VarNames t, Pretty t) => Pretty (Class t) | |
Pretty (FType Type) | |
Pretty (Exp a) | |
(Pretty a, Pretty b) => Pretty (Either a b) | |
(Pretty a, Pretty b) => Pretty (a, b) | |
(Pretty k, Pretty v) => Pretty (Map k v) | |
(Show a, Show b) => Pretty (Gr a b) | |
(Pretty a, Pretty b, Pretty c) => Pretty (a, b, c) |
getAnnotations :: Exp a -> [a] Source
minifyVars :: VarNames a => a -> a Source