ACME-0.0.0.0: Acme/Peirce.hs
{-# LANGUAGE DeriveDataTypeable #-}
-- | An interface to continuations using Peirce's law
--
-- This module is bogus, as the following proof demonstrates:
--
-- peirce (\f -> f 1 == f 2) == 1
--
-- peirce (\f -> f 2 == f 1) == 2
--
-- f 1 == f 2
--
-- Therefore, 1 == 2.
module Acme.Peirce (falseVoid, peirce, lem, doubleNeg) where
import System.IO.Unsafe
import Data.Void
import Data.Typeable
import Control.Concurrent.MVar
import Control.Exception
import Prelude hiding (catch)
data ContinueException = ContinueException deriving (Show, Typeable)
instance Exception ContinueException
-- | Ex falso
falseVoid :: Void -> a
falseVoid x = x `seq` undefined
-- | Peirce's law
peirce f = unsafePerformIO $ do
mvar <- newEmptyMVar
catch
(return $! f $ \x -> unsafePerformIO $ do
putMVar mvar $! x
throwIO ContinueException)
$ \ContinueException -> tryTakeMVar mvar
>>= maybe (throwIO ContinueException) return
-- | Law of excluded middle
lem :: (a -> b) -> ((a -> Void) -> b) -> b
lem f g = peirce $ \h -> g $ h . f
-- | Double negation law
doubleNeg f = lem id (falseVoid . f)