Skip to content

Instantly share code, notes, and snippets.

@bdonlan
Created October 18, 2011 01:17
Show Gist options
  • Save bdonlan/1294383 to your computer and use it in GitHub Desktop.
Save bdonlan/1294383 to your computer and use it in GitHub Desktop.
{-# LANGUAGE GADTs, Rank2Types #-}
import Data.Maybe (fromJust)
data SymbolicNumber s where
SymbolicNumber :: (Eq s) => (forall n. Num n => (s -> n) -> n ) -> SymbolicNumber s
evaluateSN :: (Eq s, Num n)
=> SymbolicNumber s
-> (s -> n)
-> n
evaluateSN (SymbolicNumber sn) m = sn m
liftSN2 :: Eq s
=> (forall n. Num n => n -> n -> n)
-> SymbolicNumber s
-> SymbolicNumber s
-> SymbolicNumber s
liftSN2 op (SymbolicNumber sn1) (SymbolicNumber sn2) =
SymbolicNumber $ \m -> op (sn1 m) (sn2 m)
liftSN :: Eq s
=> (forall n. Num n => n -> n)
-> SymbolicNumber s
-> SymbolicNumber s
liftSN op (SymbolicNumber sn) =
SymbolicNumber $ \m -> op (sn m)
instance Show (SymbolicNumber s) where
show = undefined
instance Eq (SymbolicNumber s) where
(==) = undefined
instance Eq s => Num (SymbolicNumber s) where
(+) = liftSN2 (+)
(*) = liftSN2 (*)
(-) = liftSN2 (-)
abs = liftSN abs
negate = liftSN negate
signum = liftSN signum
fromInteger i = SymbolicNumber $ const (fromInteger i)
var :: Eq s
=> s -> SymbolicNumber s
var n = SymbolicNumber $ ($ n)
test = evaluateSN ((var "a") + (var "b")) $ fromJust . (`lookup` [("a", 1), ("b", 4)])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment