{-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances #-} module ControlMonadPattern where import ControlMonadMatch import ControlMonadMatchInstances import Control.Monad import Control.Concurrent import System.IO.Unsafe -- pattern variables, via binders bracketed in vV Vv; -- declare variables as: vV $ \v...v-> Vv $ scope -- use as: .. (v|!) .. ==> .. (v|?) .. newtype Vv a = Vv a deriving Show -- we close an open match by providing fresh MVars -- TODO: - could we limit write access to the pattern part/monad? -- - could we use STRefs, by layering some state monad on top of the -- match monad, and limit unsafePerformIO to read access only? vV openMatch val = unsafePerformIO (close openMatch) val class Close open closed | open -> closed where close :: open -> closed instance Close (Vv match) (IO match) where close (Vv match) = return match instance Close open (IO closed) => Close (MVar a->open) (IO closed) where close open = newEmptyMVar >>= (close . open) var |! val = unsafePerformIO $ maybe (putMVar var val>>return (return ())) (\_->fail "non-linear pattern?") =<< tryTakeMVar var (|?) var = unsafePerformIO $ maybe (fail "unbound variable in pattern?") (\val->putMVar var val >> return val) =<< tryTakeMVar var (var |@ pat) val = (var |! val) >> pat val wildP x = return () -- TODO: multi-parameter patterns, -- would like or patterns, too (but need to reset variables, -- and what if we want all solutions instead of backtracking, -- and what about lazily evaluated variable reads after reset?), .. pat ==> body = \par-> pat par >> return body