Annotating Expressions
Fergus Henderson
fjh at cs.mu.OZ.AU
Wed Dec 17 12:50:38 EST 2003
On 16-Dec-2003, John Meacham <john at repetae.net> wrote:
> newtype Id a = Id a
>
> type Er f = f (E f) -- E used recursivly
> data E f = EAp (Er f) (Er f) | ELam Int (Er f) |
> ELetRec [(Int,Er f)] (Er f) | EVar Int
>
> [...] problem 2 persists. If I don't want to be constantly
> casting to and from Id, I have to use both the seperate annotated and
> unannotated versions.
>
> is this actually the case? is there a better solution I don't see? perhaps
> something using crazy GHC extensions? if not, are there any proposed
> extensions which would solve this promlem?
I think views <http://www.haskell.org/development/views.html>
would solve this problem, wouldn't they?
You could define a view of `E Id' with constructors
that skip over the conversions to/from Id
view EId of E Id = App (E Id) (E Id) | Lam Int (E Id) |
LetRec [(Int,E Id)] (E Id) | Var Int
where
eid (EAp (Id x) (Id y)) = Ap x y
eid (ELam x (Id y)) = Lam x y
eid (ELetRec (B bindings) (Id e)) = LetRec bindings' e
where bindings' = map (\(v,(Id x))->(v,x)) bindings
eid (EVar v) = Var v
Then you can traverse expressions without needing to write
any explicit conversions to/from Id, e.g.
-- "occurs v e" returns True iff v occurs somewhere in e
occurs :: Int -> (E Id) -> Bool
occurs v (Lam v1 e) = v == v1 || occurs v e
occurs v (Ap x y) = occurs v x || occurs v y
occurs v (LetRec bindings e) =
any (\(vi,ei)->v==vi || occurs v ei) bindings || occurs v e
occurs v (Var v1) = v == v1
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
More information about the Haskell
mailing list