全ての論理演算は否定論理和 (NOR) あるいは否定論理積 (NAND) のみで表現することが出来る.そのため,nor
と nand
以外の函数は全てデフォルト実装がつくれる.nor
から nand
を作ったりその逆もできるため,nor
のデフォルト実装を nand
で,nand
のデフォルト実装を nor
で書けばどちらか一方のみの実装でインスタンスになることができるようになる.
import Prelude hiding (and, or, not)
-- Warbler combinator
infixr 0 $$
($$) :: (a -> a -> b) -> a -> b
f $$ x = f x x
class Logic a where
nor :: a -> a -> a
nand :: a -> a -> a
not :: a -> a
or :: a -> a -> a
and :: a -> a -> a
xor :: a -> a -> a
xnor :: a -> a -> a
imp :: a -> a -> a
nimp :: a -> a -> a
cimp :: a -> a -> a
cnimp :: a -> a -> a
nor x y = nand $$ nand (nand $$ x) (nand $$ y)
nand x y = nor $$ nor (nor $$ x) (nor $$ y)
not = (nor $$)
or = (not .) . nor
and = (not .) . nand
xor x y = and (or x y) (nand x y)
xnor = (not .) . xor
imp = or . not
nimp = nor . not
cimp = nand . not
cnimp = and . not
instance Logic Bool where
nand True True = False
nand _ _ = True
data Bit = Zero | One
deriving (Eq, Ord, Show, Read, Bounded, Enum)
instance Logic Bit where
nor Zero Zero = One
nor _ _ = Zero
含意を imp
, 非含意を nimp
, 逆含意を cimp
, 逆非含意を cnimp
とした.