haltavista-0.1: HaltaVista/Match.hs
module HaltaVista.Match (matches) where
import HaltaVista.Types
import qualified Language.Haskell.Interpreter as I
import Control.Monad((<=<))
import Data.List
import System.Timeout(timeout)
import Control.Exception(handle, SomeException)
thres = 1500000
matches :: (String,String) -> [([Input], Output)] -> IO Bool
matches (m,f) ios = do x <- handle guard $
coerceJust `fmap` timeout thres command
return x
where command :: IO Bool
command = do res <- I.runInterpreter $ do I.setImports ["Prelude", m]
check f ios
{- runInterpreter returns Right x if the evaluation
- throws an exception. To ensure this x is evaluated
- (and the exception thrown) within `command', we need
- to seq it here. -}
case res of
Right x -> x `seq` return x
_ -> return False
guard :: SomeException -> IO Bool
guard _ = return False
coerceJust (Just b) = b
coerceJust Nothing = False
input f = prefix . intercalate " " . map I.parens
where prefix x = f ++ " " ++ x
run f ios = mapM (I.eval . input f) ios
check f ios = (and . zipWith (==) os) `fmap` run f is
where (is,os) = unzip ios