code.lukegrehan.com lambda / master Eval.hs
master

Tree @master (Download .tar.gz)

Eval.hs @masterraw · history · blame

module Eval (flatten, reduceB, beta) where
import Defs
import Data.Maybe
import Data.List
import Control.Applicative

flatten :: [Defn] -> Maybe Lambda
flatten ds = flatten' <$> main
  where
    main = snd <$> find ((== "Main").fst) resolved

    flatten' :: Lambda -> Lambda
    flatten' (Free s)  = fromMaybe (Free s) $ lookup s resolved
    flatten' (Var s)   = (Var s)
    flatten' (Abs v b) = Abs v $ flatten' b
    flatten' (App f a) = App (flatten' f) (flatten' a)

    resolved = head $ drop 10 $ iterate (map (resolve' <$>)) ds -- I am a bad person... TODO
      where
        resolve' (Var v) = (Var v)
        resolve' (Abs f b) = Abs f $ resolve' b
        resolve' (App f ar) = App (resolve' f) (resolve' ar)
        resolve' (Free f) = fromMaybe (Free f) $ lookup f ds

reduceB :: Lambda -> Lambda
reduceB l = go l (beta l)
  where 
    go p Nothing = p
    go _ (Just n) = go n (beta n)

beta :: Lambda -> Maybe Lambda
beta (Var _)            = Nothing
beta (Free _)           = Nothing
beta (Abs f b)          = Abs <$> pure f <*> beta b
beta (App (Abs v b) ar) = Just $ replace b v ar
beta (App (Free f) ar)  = App (Free f) <$> beta ar
beta (App f ar)         = App <$> beta f <*> pure ar 

replace :: Lambda -> Int -> Lambda -> Lambda 
replace (App f a) s ar = App (replace f s ar) (replace a s ar)
replace (Free s) _ _ = Free s
replace (Var s) s' ar   | s == s' = ar
                        | otherwise = Var s
replace (Abs s b) s' ar | s == s' = Abs s b
                        | otherwise = Abs s (replace b s' ar)