hermit-0.3.2.0: Haskell Equational Reasoning Model-to-Implementation Tunnel

HERMIT.Dictionary.Local.Let

Synopsis

# Rewrites on Let Expressions

Externals relating to Let expressions.

## Let Elimination

Let (NonRec v e) body ==> body[e/v]

Currently we always substitute types and coercions, and use a heuristic to decide whether to substitute expressions. This may need revisiting.

(let x = e1 in e2) ==> (e2[e1/x]), (x must not be free in e1)

As letNonRecSubstSafeR, but attempting to convert a singleton recursive binding to a non-recursive binding first.

Remove an unused non-recursive let binding. let v = E1 in E2 ==> E2, if v is not free in E2

Remove all unused recursive let bindings in the current group.

Remove all unused bindings at the top level.

## Let Introduction

e ==> (let v = e in v), name of v is provided

## Let Floating Out

(let v = ev in e) x ==> let v = ev in e x

f (let v = ev in e) ==> let v = ev in f e

let v = (let bds in e1) in e2 ==> let bds in let v = e1 in e2

( v -> let binds in e2) ==> let binds in ( v1 -> e2) Fails if v occurs in the RHS of binds. If v is shadowed in binds, then v will be alpha-renamed.

case (let bnds in e) of wild alts ==> let bnds in (case e of wild alts) Fails if any variables bound in bnds occurs in alts.

cast (let bnds in e) co ==> let bnds in cast e co

Float a Let through an expression, whatever the context.

ProgCons (NonRec v (Let bds e)) p ==> ProgCons bds (ProgCons (NonRec v e) p)

## Let Floating In

Float in a Let if possible.

let v = ev in f a ==> (let v = ev in f) (let v = ev in a)

let v = ev in case s of p -> e ==> case (let v = ev in s) of p -> let v = ev in e, if v does not shadow a pattern binder in p

let v = ev in x -> e ==> x -> let v = ev in e if v does not shadow x

## Miscallaneous

reorderNonRecLetsR :: MonadCatch m => [Name] -> Rewrite c m CoreExprSource

Re-order a sequence of nested non-recursive let bindings. The argument list should contain the let-bound variables, in the desired order.

Combine nested non-recursive lets into case of a tuple. E.g. let {v1 = e1 ; v2 = e2 ; v3 = e3} in body ==> case (e1,e2,e3) of {(v1,v2,v3) -> body}

let v = ev in e ==> case ev of v -> e