Skip to content

Instantly share code, notes, and snippets.

@jvranish
Created March 29, 2011 19:47
Show Gist options
  • Save jvranish/893085 to your computer and use it in GitHub Desktop.
Save jvranish/893085 to your computer and use it in GitHub Desktop.
Example of how to automatically lift a haskell function into a function on some AST
import Control.Monad
import Control.Monad.Error
instance Error (RuntimeError a) where
data Expr = Number Int
| SomethingElse
deriving (Show, Eq, Ord)
data Type = Func Type Type
| IntType
deriving (Show, Eq, Ord)
data RuntimeError x = ExpectedNumberGot x
| InvalidNumberOfArgs
deriving (Show, Eq, Ord)
class BType a where
fType :: a -> Type
instance BType Int where
fType _ = IntType
instance (BType a, BType b) => BType (a -> b) where
fType f = (\a -> Func (fType a) (fType $ f a)) undefined -- some sillyness to get the types to play nice
class FromExpr a where
fromExpr :: Expr -> Either (RuntimeError Expr) a
instance FromExpr Int where
fromExpr (Number x) = Right x
fromExpr x = Left (ExpectedNumberGot x)
class ToExpr a where
toExpr :: a -> Expr
instance ToExpr Int where
toExpr x = Number x
class FConvert b where
fConvert :: (FromExpr a) => (a -> b) -> [Expr] -> Either (RuntimeError Expr) (Expr, [Expr])
instance FConvert Int where
fConvert f (x:xs) = do
x' <- fromExpr x
return (toExpr $ f x', xs)
fConvert f _ = Left InvalidNumberOfArgs
instance (FromExpr a, FConvert b) => FConvert (a -> b) where
fConvert f (x:xs) = do
x' <- fromExpr x
fConvert (f x') xs
fConvert f _ = Left InvalidNumberOfArgs
add :: Int -> Int -> Int
add = (+)
test1 = fConvert add [Number 123, Number 532]
-- == Right (Number 655,[])
test2 = fType add
-- == Func IntType (Func IntType IntType)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment