packages feed

parconc-examples-0.3: parinfer/Term.hs

--
-- Adapted from the program "infer", believed to have been originally
-- authored by Philip Wadler, and used in the nofib benchmark suite
-- since at least the late 90s.
--

module Term (VarId, Term (..), freeVars) where

import Shows
import qualified Data.Set as Set
import Data.Set (Set)

type  VarId   =  String
data  Term    =  Int Int
              |  Var VarId
              |  Abs VarId Term
              |  App Term Term
              |  Let VarId Term Term

freeVars :: Term -> Set VarId
freeVars t = go t Set.empty
 where
  go (Int _) s = s
  go (Var v) s = Set.insert v s
  go (Abs v t) s = Set.delete v (go t s)
  go (App f t) s = go f (go t s)
  go (Let v a b) s = go a (Set.delete v (go b s))

instance Show Term where
      showsPrec d  =  showsTerm d

showsTerm                     :: Int -> Shows Term
showsTerm d (Int i)           =  shows i
showsTerm d (Var x)           =  showsString x
showsTerm d (Abs x v)         =  showsParenIf (d>0)
                                 (showsString "\\" . showsString x . showsAbs v)
showsTerm d (App t u)         =  showsParenIf (d>1)
                                 (showsTerm 1 t . showsChar ' ' . showsTerm 2 u)
showsTerm d (Let x u v)       =  showsParenIf (d>0)
                                 (showsString "let  "   . showsString x .
                                  showsString " = "     . showsTerm 1 u .
                                  showsString "  in  "  . showsTerm 0 v)
showsAbs                      :: Shows Term
showsAbs (Abs x t)            =  showsString " " . showsString x . showsAbs t
{- ELSE -}
showsAbs t                    =  showsString ". " . showsTerm 0 t