Consider this code:
magic :: String -> Q Exp magic s = [e| putStrLn s |]
Now, as best as I can tell, this shouldn’t actually work. Inside the Oxford brackets, s is not in scope. And yet, the above apparently works perfectly.
If we change this example slightly, it now breaks horribly:
magic :: Exp -> Q Exp magic (VarE n) = [e| putStrLn (nameBase n) |]
Just like before, we have a variable not in scope. And this time, it breaks. But it doesn’t complain about a variable not in scope; instead it whines about some undocumented class lacking an instance.
Anyone know what the heck is going on?
sis in scope inside the Oxford brackets. Basically, you’re allowed to use values of several types — those withLiftinstances — inside the quoted expression, and they’ll automatically be turned into the appropriate code to recreate the corresponding value on the other end.For example, the
Liftinstance forIntegers simply constructs the corresponding integer literal, while the instance forMaybesimply constructs the appropriate constructor applications. You can even define your own instances ofLift.You’re getting a “no instance” error because
nis aName, which isn’tLiftable.