diff --git a/colorless.cabal b/colorless.cabal
--- a/colorless.cabal
+++ b/colorless.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           colorless
-version:        2.2.17
+version:        2.2.18
 synopsis:       Colorless | The Programmatic IDL
 description:    Colorless | The Programmatic IDL
 category:       Web
diff --git a/library/Colorless/Client/Expr.hs b/library/Colorless/Client/Expr.hs
--- a/library/Colorless/Client/Expr.hs
+++ b/library/Colorless/Client/Expr.hs
@@ -23,10 +23,38 @@
   --
   , eq
   , neq
-  , add
-  , sub
-  , mul
-  , divide
+  , addI8
+  , addI16
+  , addI32
+  , addI64
+  , addU8
+  , addU16
+  , addU32
+  , addU64
+  , subI8
+  , subI16
+  , subI32
+  , subI64
+  , subU8
+  , subU16
+  , subU32
+  , subU64
+  , mulI8
+  , mulI16
+  , mulI32
+  , mulI64
+  , mulU8
+  , mulU16
+  , mulU32
+  , mulU64
+  , divI8
+  , divI16
+  , divI32
+  , divI64
+  , divU8
+  , divU16
+  , divU32
+  , divU64
   , concaT
   --
   , unit
@@ -47,6 +75,10 @@
   , list
   , eitheR
   --
+  , mapList
+  , filterList
+  , reduceList
+  --
   , tuple2
   , tuple3
   , tuple4
@@ -251,7 +283,7 @@
     y = f (ret x)
     in Stmt (stmts x ++ stmts y) (ret y)
 
-def :: HasType a => Symbol -> Expr a -> Stmt (Expr a)
+def :: (HasType a) => Symbol -> Expr a -> Stmt (Expr a)
 def symbol expr = Stmt
   { stmts = [Ast'Define $ Ast.Define symbol (toAst expr)]
   , ret = unsafeRef symbol
@@ -304,23 +336,107 @@
 --
 
 eq :: (HasType a) => Expr a -> Expr a -> Expr Bool
-eq x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "==") [toAst x, toAst y])
+eq x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "eq") [toAst x, toAst y])
 
 neq :: (HasType a) => Expr a -> Expr a -> Expr Bool
-neq x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "!=") [toAst x, toAst y])
+neq x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "neq") [toAst x, toAst y])
 
-add :: (Num a, HasType a) => Expr a -> Expr a -> Expr a
-add x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "+") [toAst x, toAst y])
+addI8 :: Expr Int8 -> Expr Int8 -> Expr Int8
+addI8 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "addI8") [toAst x, toAst y])
 
-sub :: (Num a, HasType a) => Expr a -> Expr a -> Expr a
-sub x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "-") [toAst x, toAst y])
+addI16 :: Expr Int16 -> Expr Int16 -> Expr Int16
+addI16 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "addI16") [toAst x, toAst y])
 
-mul :: (Num a, HasType a) => Expr a -> Expr a -> Expr a
-mul x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "*") [toAst x, toAst y])
+addI32 :: Expr Int32 -> Expr Int32 -> Expr Int32
+addI32 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "addI32") [toAst x, toAst y])
 
-divide :: (Num a, HasType a) => Expr a -> Expr a -> Expr a
-divide x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "/") [toAst x, toAst y])
+addI64 :: Expr Int64 -> Expr Int64 -> Expr Int64
+addI64 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "addI64") [toAst x, toAst y])
 
+addU8 :: Expr Word8 -> Expr Word8 -> Expr Word8
+addU8 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "addU8") [toAst x, toAst y])
+
+addU16 :: Expr Word16 -> Expr Word16 -> Expr Word16
+addU16 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "addU16") [toAst x, toAst y])
+
+addU32 :: Expr Word32 -> Expr Word32 -> Expr Word32
+addU32 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "addU32") [toAst x, toAst y])
+
+addU64 :: Expr Word64 -> Expr Word64 -> Expr Word64
+addU64 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "addU64") [toAst x, toAst y])
+
+subI8 :: Expr Int8 -> Expr Int8 -> Expr Int8
+subI8 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "subI8") [toAst x, toAst y])
+
+subI16 :: Expr Int16 -> Expr Int16 -> Expr Int16
+subI16 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "subI16") [toAst x, toAst y])
+
+subI32 :: Expr Int32 -> Expr Int32 -> Expr Int32
+subI32 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "subI32") [toAst x, toAst y])
+
+subI64 :: Expr Int64 -> Expr Int64 -> Expr Int64
+subI64 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "subI64") [toAst x, toAst y])
+
+subU8 :: Expr Word8 -> Expr Word8 -> Expr Word8
+subU8 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "subU8") [toAst x, toAst y])
+
+subU16 :: Expr Word16 -> Expr Word16 -> Expr Word16
+subU16 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "subU16") [toAst x, toAst y])
+
+subU32 :: Expr Word32 -> Expr Word32 -> Expr Word32
+subU32 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "subU32") [toAst x, toAst y])
+
+subU64 :: Expr Word64 -> Expr Word64 -> Expr Word64
+subU64 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "subU64") [toAst x, toAst y])
+
+mulI8 :: Expr Int8 -> Expr Int8 -> Expr Int8
+mulI8 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "mulI8") [toAst x, toAst y])
+
+mulI16 :: Expr Int16 -> Expr Int16 -> Expr Int16
+mulI16 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "mulI16") [toAst x, toAst y])
+
+mulI32 :: Expr Int32 -> Expr Int32 -> Expr Int32
+mulI32 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "mulI32") [toAst x, toAst y])
+
+mulI64 :: Expr Int64 -> Expr Int64 -> Expr Int64
+mulI64 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "mulI64") [toAst x, toAst y])
+
+mulU8 :: Expr Word8 -> Expr Word8 -> Expr Word8
+mulU8 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "mulU8") [toAst x, toAst y])
+
+mulU16 :: Expr Word16 -> Expr Word16 -> Expr Word16
+mulU16 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "mulU16") [toAst x, toAst y])
+
+mulU32 :: Expr Word32 -> Expr Word32 -> Expr Word32
+mulU32 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "mulU32") [toAst x, toAst y])
+
+mulU64 :: Expr Word64 -> Expr Word64 -> Expr Word64
+mulU64 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "mulU64") [toAst x, toAst y])
+
+divI8 :: Expr Int8 -> Expr Int8 -> Expr Int8
+divI8 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "divI8") [toAst x, toAst y])
+
+divI16 :: Expr Int16 -> Expr Int16 -> Expr Int16
+divI16 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "divI16") [toAst x, toAst y])
+
+divI32 :: Expr Int32 -> Expr Int32 -> Expr Int32
+divI32 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "divI32") [toAst x, toAst y])
+
+divI64 :: Expr Int64 -> Expr Int64 -> Expr Int64
+divI64 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "divI64") [toAst x, toAst y])
+
+divU8 :: Expr Word8 -> Expr Word8 -> Expr Word8
+divU8 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "divU8") [toAst x, toAst y])
+
+divU16 :: Expr Word16 -> Expr Word16 -> Expr Word16
+divU16 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "divU16") [toAst x, toAst y])
+
+divU32 :: Expr Word32 -> Expr Word32 -> Expr Word32
+divU32 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "divU32") [toAst x, toAst y])
+
+divU64 :: Expr Word64 -> Expr Word64 -> Expr Word64
+divU64 x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "divU64") [toAst x, toAst y])
+
 concaT :: Expr T.Text -> Expr T.Text -> Expr T.Text
 concaT x y = Expr (Ast'FnCall $ Ast.FnCall (Ast'Ref $ Ast.Ref "concat") [toAst x, toAst y])
 
@@ -1098,6 +1214,33 @@
 
 (-<) :: ToArgs args => Expr (Fn (args -> a)) -> args -> Expr a
 f -< x = call f x
+
+mapList :: Expr (Fn ((Expr (Fn (Expr a -> b)), Expr [a]) -> [b]))
+mapList = Expr (Ast'Ref $ Ast.Ref "mapList")
+
+filterList :: Expr (Fn ((Expr (Fn (Expr a -> Bool)), Expr [a]) -> [a]))
+filterList = Expr (Ast'Ref $ Ast.Ref "filterList")
+
+reduceList :: Expr (Fn ((Expr (Fn ((Expr b, Expr a) -> b)), Expr b, Expr [a]) -> b))
+reduceList = Expr (Ast'Ref $ Ast.Ref "reduceList")
+
+instance (HasType t1, HasType t2) => HasType (Fn (Expr t1 -> t2)) where
+  getType f = (getType (p1 f)) { o = Just $ (getType (p2 f)) }
+    where
+      p1 :: Proxy (Fn (Expr t1 -> t2)) -> Proxy t1
+      p1 _ = Proxy
+      p2 :: Proxy (Fn (Expr t1 -> t2)) -> Proxy t2
+      p2 _ = Proxy
+
+instance (HasType t1, HasType t2, HasType t3) => HasType (Fn ((Expr t1, Expr t2) -> t3)) where
+  getType f = (getType (p1 f)) { o = Just $ (getType (p2 f)) { o = Just $ (getType (p3 f)) } }
+    where
+      p1 :: Proxy (Fn ((Expr t1, Expr t2) -> t3)) -> Proxy t1
+      p1 _ = Proxy
+      p2 :: Proxy (Fn ((Expr t1, Expr t2) -> t3)) -> Proxy t2
+      p2 _ = Proxy
+      p3 :: Proxy (Fn ((Expr t1, Expr t2) -> t3)) -> Proxy t3
+      p3 _ = Proxy
 
 fn0
   :: (HasType a, ToAst a)
diff --git a/library/Colorless/Prim.hs b/library/Colorless/Prim.hs
--- a/library/Colorless/Prim.hs
+++ b/library/Colorless/Prim.hs
@@ -17,6 +17,8 @@
   | Prim'U16 Word16
   | Prim'U32 Word32
   | Prim'U64 Word64
+  | Prim'F32 Float
+  | Prim'F64 Double
   | Prim'String Text
   deriving (Show, Eq)
 
@@ -31,4 +33,6 @@
     Prim'U16 u -> toJSON u
     Prim'U32 u -> toJSON u
     Prim'U64 u -> toJSON u
+    Prim'F32 f -> toJSON f
+    Prim'F64 f -> toJSON f
     Prim'String s -> toJSON s
diff --git a/library/Colorless/Server/Expr.hs b/library/Colorless/Server/Expr.hs
--- a/library/Colorless/Server/Expr.hs
+++ b/library/Colorless/Server/Expr.hs
@@ -41,16 +41,17 @@
   ) where
 
 import qualified Data.Map as Map
-import Control.Monad (when, join)
+import Control.Monad (when, join, filterM)
 import Control.Monad.IO.Class (MonadIO(..))
 import Control.Monad.Reader (MonadReader(..), ReaderT(..), asks, lift)
 import Data.Map (Map)
+import Data.Foldable (foldlM)
 import Data.Int
 import Data.Word
 import Data.Aeson (parseJSON, Value)
 import Data.Aeson.Types (parseMaybe)
 import Data.IORef (IORef, readIORef, newIORef, writeIORef)
-import Data.Scientific (toBoundedInteger, Scientific)
+import Data.Scientific (toBoundedInteger, toBoundedRealFloat, Scientific)
 import Data.Text (Text)
 
 import qualified Colorless.Ast as Ast
@@ -61,7 +62,10 @@
 import Colorless.RuntimeThrower
 
 data EvalConfig m = EvalConfig
-  { options :: Options
+  { limits :: Limits
+  , langServiceCallCount :: IORef Int
+  , langLambdaCount :: IORef Int
+  , langExprCount :: IORef Int
   , apiCall :: ApiCall -> m Val
   }
 
@@ -74,9 +78,27 @@
 instance RuntimeThrower m => RuntimeThrower (Eval m) where
   runtimeThrow err = Eval (lift $ runtimeThrow err)
 
-getOptions :: Monad m => Eval m Options
-getOptions = asks options
+tick :: (MonadIO m, RuntimeThrower m) => (Limits -> Maybe Int) -> (EvalConfig m -> IORef Int) -> (Int -> RuntimeError) -> Eval m ()
+tick getLimit langCount err = do
+  limit' <- getLimit <$> asks limits
+  case limit' of
+    Nothing -> return ()
+    Just limit -> do
+      ref <- asks langCount
+      count <- liftIO $ readIORef ref
+      if count == limit
+        then runtimeThrow (err count)
+        else liftIO $ writeIORef ref (count + 1)
 
+tickServiceCall :: (MonadIO m, RuntimeThrower m) => Eval m ()
+tickServiceCall = tick serviceCallLimit langServiceCallCount RuntimeError'LangServiceCallLimit
+
+tickLambda :: (MonadIO m, RuntimeThrower m) => Eval m ()
+tickLambda = tick lambdaLimit langLambdaCount RuntimeError'LangLambdaLimit
+
+tickExpr :: (MonadIO m, RuntimeThrower m) => Eval m ()
+tickExpr = tick exprLimit langExprCount RuntimeError'LangExprLimit
+
 type Env m = Map Symbol (IORef (Expr m))
 
 runEval :: MonadIO m => Eval m a -> EvalConfig m -> m a
@@ -280,6 +302,7 @@
 
 evalRef :: (MonadIO m, RuntimeThrower m) => Ref -> IORef (Env m) -> Eval m (Expr m)
 evalRef Ref{symbol} envRef = do
+  tickExpr
   env <- liftIO $ readIORef envRef
   varLookup env symbol
 
@@ -306,6 +329,7 @@
 
 evalIf :: (MonadIO m, RuntimeThrower m) => If m -> IORef (Env m) -> Eval m (Expr m)
 evalIf If{cond, true, false} envRef = do
+  tickExpr
   envRef' <- liftIO $ newIORef =<< readIORef envRef
   v <- eval cond envRef'
   case v of
@@ -315,7 +339,9 @@
     _ -> runtimeThrow RuntimeError'IncompatibleType
 
 evalGet :: (MonadIO m, RuntimeThrower m) => Get m -> IORef (Env m) -> Eval m (Expr m)
-evalGet Get{path,expr} envRef = getter path =<< eval expr envRef
+evalGet Get{path,expr} envRef = do
+  tickExpr
+  getter path =<< eval expr envRef
 
 getter :: (MonadIO m, RuntimeThrower m) => [Text] -> Expr m -> Eval m (Expr m)
 getter [] expr = return expr
@@ -340,51 +366,55 @@
 
 evalDefine :: (MonadIO m, RuntimeThrower m) => Define m -> IORef (Env m) -> Eval m (Expr m)
 evalDefine Define{var, expr} envRef = do
+  tickExpr
   expr' <- eval expr envRef
   env <- liftIO $ readIORef envRef
   ref <- liftIO $ newIORef expr'
-  limit <- hardVariableLimit <$> getOptions
+  limit <- variableLimit <$> asks limits
   addVarToEnv limit envRef var ref env
   return expr'
 
 evalLambda :: (MonadIO m, RuntimeThrower m) => Lambda m -> IORef (Env m) -> Eval m (Expr m)
 evalLambda Lambda{params, expr} envRef = do
-  disabled <- hardDisableLambdas <$> getOptions
-  if disabled
-    then runtimeThrow $ RuntimeError'LambdaNotPermitted
-    else
-      return . Expr'Fn . Fn $ \vals -> do
-        let keys = map fst params
-        let args = zip keys vals
-        let keysLen = length keys
-        let argsLen = length args
-        if keysLen /= argsLen
-          then runtimeThrow $ if keysLen < argsLen
-            then RuntimeError'TooManyArguments
-            else RuntimeError'TooFewArguments
-          else do
-            args' <- liftIO $ mapM newIORef (Map.fromList args)
-            limit <- hardVariableLimit <$> getOptions
-            envRef' <- addEnvToEnv limit args' envRef
-            eval expr envRef'
+  tickLambda
+  tickExpr
+  return . Expr'Fn . Fn $ \vals -> do
+    let keys = map fst params
+    let args = zip keys vals
+    let keysLen = length keys
+    let argsLen = length args
+    if keysLen /= argsLen
+      then runtimeThrow $ if keysLen < argsLen
+        then RuntimeError'TooManyArguments
+        else RuntimeError'TooFewArguments
+      else do
+        args' <- liftIO $ mapM newIORef (Map.fromList args)
+        limit <- variableLimit <$> asks limits
+        envRef' <- addEnvToEnv limit args' envRef
+        eval expr envRef'
 
 evalList :: (MonadIO m, RuntimeThrower m) => List m -> IORef (Env m)-> Eval m (Expr m)
 evalList List{list} envRef = do
+  tickExpr
   list' <- mapM (\item -> eval item envRef) list
   return . Expr'List $ List list'
 
 evalTuple :: (MonadIO m, RuntimeThrower m) => Tuple m -> IORef (Env m)-> Eval m (Expr m)
 evalTuple Tuple{tuple} envRef = do
+  tickExpr
   tuple' <- mapM (\item -> eval item envRef) tuple
   return . Expr'Tuple $ Tuple tuple'
 
 evalDo :: (MonadIO m, RuntimeThrower m) => Do m -> IORef (Env m) -> Eval m (Expr m)
-evalDo Do{exprs} envRef = case exprs of
-  [] -> return $ Expr'Val $ Val'Const $ Const'Null
-  _ -> last <$> mapM (\expr -> eval expr envRef) exprs
+evalDo Do{exprs} envRef = do
+  tickExpr
+  case exprs of
+    [] -> return $ Expr'Val $ Val'Const $ Const'Null
+    _ -> last <$> mapM (\expr -> eval expr envRef) exprs
 
 evalFnCall :: (MonadIO m, RuntimeThrower m) => FnCall m -> IORef (Env m) -> Eval m (Expr m)
 evalFnCall FnCall{fn, args} envRef = do
+  tickExpr
   val <- eval fn envRef
   case val of
     Expr'Fn (Fn fn') -> do
@@ -401,11 +431,14 @@
     _ -> runtimeThrow RuntimeError'IncompatibleType
 
 evalApiUnCall :: (MonadIO m, RuntimeThrower m) => ApiUnCall m -> IORef (Env m) -> Eval m (Expr m)
-evalApiUnCall apiUnCall envRef = Expr'Val <$> case apiUnCall of
-  ApiUnCall'HollowUnCall c -> evalHollowUnCall c
-  ApiUnCall'WrapUnCall c -> evalWrapUnCall c envRef
-  ApiUnCall'StructUnCall c -> evalStructUnCall c envRef
-  ApiUnCall'EnumerationUnCall c -> evalEnumerationUnCall c envRef
+evalApiUnCall apiUnCall envRef = do
+  tickServiceCall
+  tickExpr
+  Expr'Val <$> case apiUnCall of
+    ApiUnCall'HollowUnCall c -> evalHollowUnCall c
+    ApiUnCall'WrapUnCall c -> evalWrapUnCall c envRef
+    ApiUnCall'StructUnCall c -> evalStructUnCall c envRef
+    ApiUnCall'EnumerationUnCall c -> evalEnumerationUnCall c envRef
 
 evalHollowUnCall :: (MonadIO m, RuntimeThrower m) => HollowUnCall -> Eval m Val
 evalHollowUnCall HollowUnCall{n} =
@@ -441,108 +474,330 @@
   eq <- newIORef eqExpr
   neq <- newIORef neqExpr
   concat' <- newIORef concatExpr
-  add <- newIORef addExpr
-  sub <- newIORef subExpr
-  mul <- newIORef mulExpr
-  div' <- newIORef divExpr
+
+  addI8 <- newIORef $ i8Expr (+)
+  addI16 <- newIORef $ i16Expr (+)
+  addI32 <- newIORef $ i32Expr (+)
+  addI64 <- newIORef $ i64Expr (+)
+  addU8 <- newIORef $ u8Expr (+)
+  addU16 <- newIORef $ u16Expr (+)
+  addU32 <- newIORef $ u32Expr (+)
+  addU64 <- newIORef $ u64Expr (+)
+  addF32 <- newIORef $ f32Expr (+)
+  addF64 <- newIORef $ f64Expr (+)
+
+  subI8 <- newIORef $ i8Expr (-)
+  subI16 <- newIORef $ i16Expr (-)
+  subI32 <- newIORef $ i32Expr (-)
+  subI64 <- newIORef $ i64Expr (-)
+  subU8 <- newIORef $ u8Expr (-)
+  subU16 <- newIORef $ u16Expr (-)
+  subU32 <- newIORef $ u32Expr (-)
+  subU64 <- newIORef $ u64Expr (-)
+  subF32 <- newIORef $ f32Expr (-)
+  subF64 <- newIORef $ f64Expr (-)
+
+  mulI8 <- newIORef $ i8Expr (*)
+  mulI16 <- newIORef $ i16Expr (*)
+  mulI32 <- newIORef $ i32Expr (*)
+  mulI64 <- newIORef $ i64Expr (*)
+  mulU8 <- newIORef $ u8Expr (*)
+  mulU16 <- newIORef $ u16Expr (*)
+  mulU32 <- newIORef $ u32Expr (*)
+  mulU64 <- newIORef $ u64Expr (*)
+  mulF32 <- newIORef $ f32Expr (*)
+  mulF64 <- newIORef $ f64Expr (*)
+
+  divI8 <- newIORef $ i8Expr (div)
+  divI16 <- newIORef $ i16Expr (div)
+  divI32 <- newIORef $ i32Expr (div)
+  divI64 <- newIORef $ i64Expr (div)
+  divU8 <- newIORef $ u8Expr (div)
+  divU16 <- newIORef $ u16Expr (div)
+  divU32 <- newIORef $ u32Expr (div)
+  divU64 <- newIORef $ u64Expr (div)
+  divF32 <- newIORef $ f32Expr (/)
+  divF64 <- newIORef $ f64Expr (/)
+
   tuple <- newIORef tupleExpr
+
+  mapList <- newIORef mapListExpr
+  filterList <- newIORef filterListExpr
+  reduceList <- newIORef reduceListExpr
+
   newIORef $ Map.fromList
-    [ ("==", eq)
-    , ("!=", neq)
-    , ("+", add)
-    , ("-", sub)
-    , ("*", mul)
-    , ("/", div')
+    [ ("eq", eq)
+    , ("neq", neq)
+
+    , ("addI8", addI8)
+    , ("addI16", addI16)
+    , ("addI32", addI32)
+    , ("addI64", addI64)
+    , ("addU8", addU8)
+    , ("addU16", addU16)
+    , ("addU32", addU32)
+    , ("addU64", addU64)
+    , ("addF32", addF32)
+    , ("addF64", addF64)
+
+    , ("subI8", subI8)
+    , ("subI16", subI16)
+    , ("subI32", subI32)
+    , ("subI64", subI64)
+    , ("subU8", subU8)
+    , ("subU16", subU16)
+    , ("subU32", subU32)
+    , ("subU64", subU64)
+    , ("subF32", subF32)
+    , ("subF64", subF64)
+
+    , ("mulI8", mulI8)
+    , ("mulI16", mulI16)
+    , ("mulI32", mulI32)
+    , ("mulI64", mulI64)
+    , ("mulU8", mulU8)
+    , ("mulU16", mulU16)
+    , ("mulU32", mulU32)
+    , ("mulU64", mulU64)
+    , ("mulF32", mulF32)
+    , ("mulF64", mulF64)
+
+    , ("divI8", divI8)
+    , ("divI16", divI16)
+    , ("divI32", divI32)
+    , ("divI64", divI64)
+    , ("divU8", divU8)
+    , ("divU16", divU16)
+    , ("divU32", divU32)
+    , ("divU64", divU64)
+    , ("divF32", divF32)
+    , ("divF64", divF64)
+
     , ("concat", concat')
     , ("tuple", tuple)
+
+    , ("mapList", mapList)
+    , ("filterList", filterList)
+    , ("reduceList", reduceList)
+
     ]
 
-numExpr :: RuntimeThrower m
-  => (Scientific -> Scientific -> Scientific)
-  -> (Int8 -> Int8 -> Int8)
-  -> (Int16 -> Int16 -> Int16)
-  -> (Int32 -> Int32 -> Int32)
-  -> (Int64 -> Int64 -> Int64)
-  -> (Word8 -> Word8 -> Word8)
-  -> (Word16 -> Word16 -> Word16)
-  -> (Word32 -> Word32 -> Word32)
-  -> (Word64 -> Word64 -> Word64)
-  -> Expr m
-numExpr num i8 i16 i32 i64 u8 u16 u32 u64 = Expr'Fn . Fn $ \args ->
+mapListExpr :: RuntimeThrower m => Expr m
+mapListExpr = Expr'Fn . Fn $ \args ->
   case args of
     (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
-    [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Const (Const'Number y))] -> return $
-      Expr'Val $ Val'Const $ Const'Number $ x `num` y
+    [Expr'Fn (Fn f), Expr'List (List list)] -> Expr'List . List <$> mapM (f . (:[])) list
+    (_:_:[]) -> runtimeThrow RuntimeError'IncompatibleType
+    _ -> runtimeThrow RuntimeError'TooManyArguments
 
-    [Expr'Val (Val'Prim (Prim'I8 x)), Expr'Val (Val'Prim (Prim'I8 y))] -> toExpr $ x `i8` y
+filterListExpr :: RuntimeThrower m => Expr m
+filterListExpr = Expr'Fn . Fn $ \args ->
+  case args of
+    (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
+    [Expr'Fn (Fn f), Expr'List (List list)] -> Expr'List . List <$>
+      filterM
+      (\x -> do
+        res <- f [x]
+        case res of
+          Expr'Val (Val'Prim (Prim'Bool b)) -> return b
+          Expr'Val (Val'Const (Const'Bool b)) -> return b
+          _ -> runtimeThrow RuntimeError'IncompatibleType) -- Bool
+      list
+    (_:_:[]) -> runtimeThrow RuntimeError'IncompatibleType
+    _ -> runtimeThrow RuntimeError'TooManyArguments
+
+reduceListExpr :: RuntimeThrower m => Expr m
+reduceListExpr = Expr'Fn . Fn $ \args ->
+  case args of
+    (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
+    [Expr'Fn (Fn f), a, Expr'List (List list)] -> foldlM (\x y -> f [x, y]) a list
+    (_:_:[]) -> runtimeThrow RuntimeError'IncompatibleType
+    _ -> runtimeThrow RuntimeError'TooManyArguments
+
+i8Expr :: RuntimeThrower m => (Int8 -> Int8 -> Int8) -> Expr m
+i8Expr op = Expr'Fn . Fn $ \args ->
+  case args of
+    (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
+    [Expr'Val (Val'Prim (Prim'I8 x)), Expr'Val (Val'Prim (Prim'I8 y))] -> toExpr $ x `op` y
     [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Prim (Prim'I8 y))] -> case toBoundedInteger x of
-      Just x' -> toExpr $ x' `i8` y
+      Just x' -> toExpr $ x' `op` y
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
     [Expr'Val (Val'Prim (Prim'I8 x)), Expr'Val (Val'Const (Const'Number y))] -> case toBoundedInteger y of
-      Just y' -> toExpr $ x `i8` y'
+      Just y' -> toExpr $ x `op` y'
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
+    [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Const (Const'Number y))] -> case (toBoundedInteger x, toBoundedInteger y) of
+      (Just x', Just y') -> toExpr $ x' `op` y'
+      _ -> runtimeThrow RuntimeError'IncompatibleType
+    (_:_:[]) -> runtimeThrow RuntimeError'IncompatibleType
+    _ -> runtimeThrow RuntimeError'TooManyArguments
+    where
+      toExpr v = return $ Expr'Val (toVal v)
 
-    [Expr'Val (Val'Prim (Prim'I16 x)), Expr'Val (Val'Prim (Prim'I16 y))] -> toExpr $ x `i16` y
+i16Expr :: RuntimeThrower m => (Int16 -> Int16 -> Int16) -> Expr m
+i16Expr op = Expr'Fn . Fn $ \args ->
+  case args of
+    (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
+    [Expr'Val (Val'Prim (Prim'I16 x)), Expr'Val (Val'Prim (Prim'I16 y))] -> toExpr $ x `op` y
     [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Prim (Prim'I16 y))] -> case toBoundedInteger x of
-      Just x' -> toExpr $ x' `i16` y
+      Just x' -> toExpr $ x' `op` y
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
     [Expr'Val (Val'Prim (Prim'I16 x)), Expr'Val (Val'Const (Const'Number y))] -> case toBoundedInteger y of
-      Just y' -> toExpr $ x `i16` y'
+      Just y' -> toExpr $ x `op` y'
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
+    [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Const (Const'Number y))] -> case (toBoundedInteger x, toBoundedInteger y) of
+      (Just x', Just y') -> toExpr $ x' `op` y'
+      _ -> runtimeThrow RuntimeError'IncompatibleType
+    (_:_:[]) -> runtimeThrow RuntimeError'IncompatibleType
+    _ -> runtimeThrow RuntimeError'TooManyArguments
+    where
+      toExpr v = return $ Expr'Val (toVal v)
 
-    [Expr'Val (Val'Prim (Prim'I32 x)), Expr'Val (Val'Prim (Prim'I32 y))] -> toExpr $ x `i32` y
+i32Expr :: RuntimeThrower m => (Int32 -> Int32 -> Int32) -> Expr m
+i32Expr op = Expr'Fn . Fn $ \args ->
+  case args of
+    (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
+    [Expr'Val (Val'Prim (Prim'I32 x)), Expr'Val (Val'Prim (Prim'I32 y))] -> toExpr $ x `op` y
     [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Prim (Prim'I32 y))] -> case toBoundedInteger x of
-      Just x' -> toExpr $ x' `i32` y
+      Just x' -> toExpr $ x' `op` y
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
     [Expr'Val (Val'Prim (Prim'I32 x)), Expr'Val (Val'Const (Const'Number y))] -> case toBoundedInteger y of
-      Just y' -> toExpr $ x `i32` y'
+      Just y' -> toExpr $ x `op` y'
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
+    [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Const (Const'Number y))] -> case (toBoundedInteger x, toBoundedInteger y) of
+      (Just x', Just y') -> toExpr $ x' `op` y'
+      _ -> runtimeThrow RuntimeError'IncompatibleType
+    (_:_:[]) -> runtimeThrow RuntimeError'IncompatibleType
+    _ -> runtimeThrow RuntimeError'TooManyArguments
+    where
+      toExpr v = return $ Expr'Val (toVal v)
 
-    [Expr'Val (Val'Prim (Prim'I64 x)), Expr'Val (Val'Prim (Prim'I64 y))] -> toExpr $ x `i64` y
+i64Expr :: RuntimeThrower m => (Int64 -> Int64 -> Int64) -> Expr m
+i64Expr op = Expr'Fn . Fn $ \args ->
+  case args of
+    (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
+    [Expr'Val (Val'Prim (Prim'I64 x)), Expr'Val (Val'Prim (Prim'I64 y))] -> toExpr $ x `op` y
     [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Prim (Prim'I64 y))] -> case toBoundedInteger x of
-      Just x' -> toExpr $ x' `i64` y
+      Just x' -> toExpr $ x' `op` y
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
     [Expr'Val (Val'Prim (Prim'I64 x)), Expr'Val (Val'Const (Const'Number y))] -> case toBoundedInteger y of
-      Just y' -> toExpr $ x `i64` y'
+      Just y' -> toExpr $ x `op` y'
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
+    [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Const (Const'Number y))] -> case (toBoundedInteger x, toBoundedInteger y) of
+      (Just x', Just y') -> toExpr $ x' `op` y'
+      _ -> runtimeThrow RuntimeError'IncompatibleType
+    (_:_:[]) -> runtimeThrow RuntimeError'IncompatibleType
+    _ -> runtimeThrow RuntimeError'TooManyArguments
+    where
+      toExpr v = return $ Expr'Val (toVal v)
 
-    [Expr'Val (Val'Prim (Prim'U8 x)), Expr'Val (Val'Prim (Prim'U8 y))] -> toExpr $ x `u8` y
+u8Expr :: RuntimeThrower m => (Word8 -> Word8 -> Word8) -> Expr m
+u8Expr op = Expr'Fn . Fn $ \args ->
+  case args of
+    (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
+    [Expr'Val (Val'Prim (Prim'U8 x)), Expr'Val (Val'Prim (Prim'U8 y))] -> toExpr $ x `op` y
     [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Prim (Prim'U8 y))] -> case toBoundedInteger x of
-      Just x' -> toExpr $ x' `u8` y
+      Just x' -> toExpr $ x' `op` y
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
     [Expr'Val (Val'Prim (Prim'U8 x)), Expr'Val (Val'Const (Const'Number y))] -> case toBoundedInteger y of
-      Just y' -> toExpr $ x `u8` y'
+      Just y' -> toExpr $ x `op` y'
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
+    [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Const (Const'Number y))] -> case (toBoundedInteger x, toBoundedInteger y) of
+      (Just x', Just y') -> toExpr $ x' `op` y'
+      _ -> runtimeThrow RuntimeError'IncompatibleType
+    (_:_:[]) -> runtimeThrow RuntimeError'IncompatibleType
+    _ -> runtimeThrow RuntimeError'TooManyArguments
+    where
+      toExpr v = return $ Expr'Val (toVal v)
 
-    [Expr'Val (Val'Prim (Prim'U16 x)), Expr'Val (Val'Prim (Prim'U16 y))] -> toExpr $ x `u16` y
+u16Expr :: RuntimeThrower m => (Word16 -> Word16 -> Word16) -> Expr m
+u16Expr op = Expr'Fn . Fn $ \args ->
+  case args of
+    (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
+    [Expr'Val (Val'Prim (Prim'U16 x)), Expr'Val (Val'Prim (Prim'U16 y))] -> toExpr $ x `op` y
     [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Prim (Prim'U16 y))] -> case toBoundedInteger x of
-      Just x' -> toExpr $ x' `u16` y
+      Just x' -> toExpr $ x' `op` y
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
     [Expr'Val (Val'Prim (Prim'U16 x)), Expr'Val (Val'Const (Const'Number y))] -> case toBoundedInteger y of
-      Just y' -> toExpr $ x `u16` y'
+      Just y' -> toExpr $ x `op` y'
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
+    [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Const (Const'Number y))] -> case (toBoundedInteger x, toBoundedInteger y) of
+      (Just x', Just y') -> toExpr $ x' `op` y'
+      _ -> runtimeThrow RuntimeError'IncompatibleType
+    (_:_:[]) -> runtimeThrow RuntimeError'IncompatibleType
+    _ -> runtimeThrow RuntimeError'TooManyArguments
+    where
+      toExpr v = return $ Expr'Val (toVal v)
 
-    [Expr'Val (Val'Prim (Prim'U32 x)), Expr'Val (Val'Prim (Prim'U32 y))] -> toExpr $ x `u32` y
+u32Expr :: RuntimeThrower m => (Word32 -> Word32 -> Word32) -> Expr m
+u32Expr op = Expr'Fn . Fn $ \args ->
+  case args of
+    (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
+    [Expr'Val (Val'Prim (Prim'U32 x)), Expr'Val (Val'Prim (Prim'U32 y))] -> toExpr $ x `op` y
     [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Prim (Prim'U32 y))] -> case toBoundedInteger x of
-      Just x' -> toExpr $ x' `u32` y
+      Just x' -> toExpr $ x' `op` y
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
     [Expr'Val (Val'Prim (Prim'U32 x)), Expr'Val (Val'Const (Const'Number y))] -> case toBoundedInteger y of
-      Just y' -> toExpr $ x `u32` y'
+      Just y' -> toExpr $ x `op` y'
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
+    [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Const (Const'Number y))] -> case (toBoundedInteger x, toBoundedInteger y) of
+      (Just x', Just y') -> toExpr $ x' `op` y'
+      _ -> runtimeThrow RuntimeError'IncompatibleType
+    (_:_:[]) -> runtimeThrow RuntimeError'IncompatibleType
+    _ -> runtimeThrow RuntimeError'TooManyArguments
+    where
+      toExpr v = return $ Expr'Val (toVal v)
 
-    [Expr'Val (Val'Prim (Prim'U64 x)), Expr'Val (Val'Prim (Prim'U64 y))] -> toExpr $ x `u64` y
+u64Expr :: RuntimeThrower m => (Word64 -> Word64 -> Word64) -> Expr m
+u64Expr op = Expr'Fn . Fn $ \args ->
+  case args of
+    (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
+    [Expr'Val (Val'Prim (Prim'U64 x)), Expr'Val (Val'Prim (Prim'U64 y))] -> toExpr $ x `op` y
     [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Prim (Prim'U64 y))] -> case toBoundedInteger x of
-      Just x' -> toExpr $ x' `u64` y
+      Just x' -> toExpr $ x' `op` y
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
     [Expr'Val (Val'Prim (Prim'U64 x)), Expr'Val (Val'Const (Const'Number y))] -> case toBoundedInteger y of
-      Just y' -> toExpr $ x `u64` y'
+      Just y' -> toExpr $ x `op` y'
       Nothing -> runtimeThrow RuntimeError'IncompatibleType
+    [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Const (Const'Number y))] -> case (toBoundedInteger x, toBoundedInteger y) of
+      (Just x', Just y') -> toExpr $ x' `op` y'
+      _ -> runtimeThrow RuntimeError'IncompatibleType
+    (_:_:[]) -> runtimeThrow RuntimeError'IncompatibleType
+    _ -> runtimeThrow RuntimeError'TooManyArguments
+    where
+      toExpr v = return $ Expr'Val (toVal v)
 
+f32Expr :: RuntimeThrower m => (Float -> Float -> Float) -> Expr m
+f32Expr op = Expr'Fn . Fn $ \args ->
+  case args of
+    (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
+    [Expr'Val (Val'Prim (Prim'F32 x)), Expr'Val (Val'Prim (Prim'F32 y))] -> toExpr $ x `op` y
+    [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Prim (Prim'F32 y))] -> case toBoundedRealFloat x of
+      x' -> toExpr $ eitherCollapse x' `op` y
+    [Expr'Val (Val'Prim (Prim'F32 x)), Expr'Val (Val'Const (Const'Number y))] -> case toBoundedRealFloat y of
+      y' -> toExpr $ x `op` eitherCollapse y'
+    [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Const (Const'Number y))] -> case (toBoundedRealFloat x, toBoundedRealFloat y) of
+      (x', y') -> toExpr $ eitherCollapse x' `op` eitherCollapse y'
     (_:_:[]) -> runtimeThrow RuntimeError'IncompatibleType
     _ -> runtimeThrow RuntimeError'TooManyArguments
     where
       toExpr v = return $ Expr'Val (toVal v)
 
+f64Expr :: RuntimeThrower m => (Double -> Double -> Double) -> Expr m
+f64Expr op = Expr'Fn . Fn $ \args ->
+  case args of
+    (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
+    [Expr'Val (Val'Prim (Prim'F64 x)), Expr'Val (Val'Prim (Prim'F64 y))] -> toExpr $ x `op` y
+    [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Prim (Prim'F64 y))] -> case toBoundedRealFloat x of
+      x' -> toExpr $ eitherCollapse x' `op` y
+    [Expr'Val (Val'Prim (Prim'F64 x)), Expr'Val (Val'Const (Const'Number y))] -> case toBoundedRealFloat y of
+      y' -> toExpr $ x `op` eitherCollapse y'
+    [Expr'Val (Val'Const (Const'Number x)), Expr'Val (Val'Const (Const'Number y))] -> case (toBoundedRealFloat x, toBoundedRealFloat y) of
+      (x', y') -> toExpr $ eitherCollapse x' `op` eitherCollapse y'
+    (_:_:[]) -> runtimeThrow RuntimeError'IncompatibleType
+    _ -> runtimeThrow RuntimeError'TooManyArguments
+    where
+      toExpr v = return $ Expr'Val (toVal v)
+
 boolExpr :: RuntimeThrower m
   => (Scientific -> Scientific -> Bool)
   -> (Int8 -> Int8 -> Bool)
@@ -641,29 +896,24 @@
 concatExpr = Expr'Fn . Fn $ \args ->
   case args of
     (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
-    [x, y] -> case (x,y) of
-      (Expr'Val (Val'Const (Const'String x')), Expr'Val (Val'Const (Const'String y'))) -> return $
-        Expr'Val . Val'Const . Const'String $ x' `mappend` y'
-      _ -> runtimeThrow RuntimeError'IncompatibleType
+    [x, y] -> do
+      (u,v) <- case (x,y) of
+        (Expr'Val (Val'Const (Const'String x')), Expr'Val (Val'Const (Const'String y'))) -> return (x',y')
+        (Expr'Val (Val'Prim (Prim'String x')), Expr'Val (Val'Prim (Prim'String y'))) -> return (x',y')
+        (Expr'Val (Val'Const (Const'String x')), Expr'Val (Val'Prim (Prim'String y'))) -> return (x',y')
+        (Expr'Val (Val'Prim (Prim'String x')), Expr'Val (Val'Const (Const'String y'))) -> return (x',y')
+        _ -> runtimeThrow RuntimeError'IncompatibleType -- String
+      return $ Expr'Val . Val'Const . Const'String $ u `mappend` v
     _ -> runtimeThrow RuntimeError'TooManyArguments
 
-addExpr :: RuntimeThrower m => Expr m
-addExpr = numExpr (+) (+) (+) (+) (+) (+) (+) (+) (+)
-
-subExpr :: RuntimeThrower m => Expr m
-subExpr = numExpr (-) (-) (-) (-) (-) (-) (-) (-) (-)
-
-mulExpr :: RuntimeThrower m => Expr m
-mulExpr = numExpr (*) (*) (*) (*) (*) (*) (*) (*) (*)
-
-divExpr :: RuntimeThrower m => Expr m
-divExpr = numExpr (/) div div div div div div div div
-
 tupleExpr :: RuntimeThrower m => Expr m
 tupleExpr = Expr'Fn . Fn $ \args ->
   case args of
     (_:[]) -> runtimeThrow RuntimeError'TooFewArguments
     xs -> return $ Expr'Tuple $ Tuple xs
+
+eitherCollapse :: Either a a -> a
+eitherCollapse = either id id
 
 --
 
diff --git a/library/Colorless/Types.hs b/library/Colorless/Types.hs
--- a/library/Colorless/Types.hs
+++ b/library/Colorless/Types.hs
@@ -7,8 +7,10 @@
   , Pull(..)
   , pullAddress
   , RuntimeError(..)
-  , Options(..)
-  , defOptions
+  , Hooks(..)
+  , Limits(..)
+  , defLimits
+  , defHooks
   --
   , Symbol(..)
   , Type(..)
@@ -22,7 +24,7 @@
 
 import qualified Data.HashMap.Lazy as HML
 import Control.Monad (mzero)
-import Data.Aeson hiding (Options)
+import Data.Aeson
 import Data.Text (Text)
 import Data.Text.Conversions (toText)
 import Data.String (IsString(..))
@@ -66,6 +68,9 @@
   = RuntimeError'UnparsableFormat
   | RuntimeError'UnrecognizedCall
   | RuntimeError'VariableLimit
+  | RuntimeError'LangServiceCallLimit Int
+  | RuntimeError'LangLambdaLimit Int
+  | RuntimeError'LangExprLimit Int
   | RuntimeError'UnknownVariable Text
   | RuntimeError'IncompatibleType
   | RuntimeError'TooFewArguments
@@ -82,7 +87,6 @@
   | RuntimeError'UnparsableQuery
   | RuntimeError'NoImplementation
   | RuntimeError'NotMember
-  | RuntimeError'LambdaNotPermitted
   deriving (Show, Eq)
 
 instance ToJSON RuntimeError where
@@ -90,6 +94,9 @@
     RuntimeError'UnparsableFormat -> e "UnparsableFormat"
     RuntimeError'UnrecognizedCall -> object [ "tag" .= String "UnrecognizedCall" ]
     RuntimeError'VariableLimit -> e "VariableLimit"
+    RuntimeError'LangExprLimit l -> object [ "tag" .= String "LangExprLimit", "limit" .= l ]
+    RuntimeError'LangLambdaLimit l -> object [ "tag" .= String "LangLambdaLimit", "limit" .= l ]
+    RuntimeError'LangServiceCallLimit l -> object [ "tag" .= String "LangServiceCallLimit", "limit" .= l ]
     RuntimeError'UnknownVariable m -> object [ "tag" .= String "UnknownVariable", "name" .= m ]
     RuntimeError'IncompatibleType -> e "IncompatibleType"
     RuntimeError'TooFewArguments -> e "TooFewArguments"
@@ -106,7 +113,6 @@
     RuntimeError'UnparsableQuery -> e "UnparsableQuery"
     RuntimeError'NoImplementation -> e "NoImplementation"
     RuntimeError'NotMember -> e "NotMember"
-    RuntimeError'LambdaNotPermitted -> e "LambdaNotPermitted"
     where
       e s = object [ "tag" .= String s ]
 
@@ -117,6 +123,9 @@
       "UnparsableFormat" -> pure RuntimeError'UnparsableFormat
       "UnrecognizedCall" -> pure RuntimeError'UnrecognizedCall
       "VariableLimit" -> pure RuntimeError'VariableLimit
+      "LangExprLimit" -> RuntimeError'LangExprLimit <$> o .: "limit"
+      "LangLambdaLimit" -> RuntimeError'LangLambdaLimit <$> o .: "limit"
+      "LangServiceCallLimit" -> RuntimeError'LangServiceCallLimit <$> o .: "limit"
       "UnknownVariable" -> RuntimeError'UnknownVariable <$> o .: "name"
       "IncompatibleType" -> pure RuntimeError'IncompatibleType
       "TooFewArguments" -> pure RuntimeError'TooFewArguments
@@ -133,21 +142,35 @@
       "UnparsableQuery" -> pure RuntimeError'UnparsableQuery
       "NoImplementation" -> pure RuntimeError'NoImplementation
       "NotMember" -> pure RuntimeError'NotMember
-      "LambdaNotPermitted" -> pure RuntimeError'LambdaNotPermitted
       _ -> mzero
   parseJSON _ = mzero
 
-data Options = Options
-  { hardVariableLimit :: Maybe Int
-  , hardDisableLambdas :: Bool
+data Limits = Limits
+  { variableLimit :: Maybe Int
+  , serviceCallLimit :: Maybe Int
+  , lambdaLimit :: Maybe Int
+  , exprLimit :: Maybe Int
   } deriving (Show, Eq)
 
-defOptions :: Options
-defOptions = Options
-  { hardVariableLimit = Just 100
-  , hardDisableLambdas = True
+defLimits :: Limits
+defLimits = Limits
+  { variableLimit = Just 50
+  , serviceCallLimit = Just 50
+  , lambdaLimit = Just 10
+  , exprLimit = Just 100
   }
 
+data Hooks m meta meta' = Hooks
+  { metaMiddleware :: meta -> m meta'
+  , sandboxLimits :: meta' -> m Limits
+  }
+
+defHooks :: Monad m => Hooks m meta meta
+defHooks = Hooks
+  { metaMiddleware = return
+  , sandboxLimits = \_ -> return defLimits
+  }
+
 --
 
 newtype Symbol = Symbol Text
@@ -156,26 +179,33 @@
 data Type = Type
   { n :: TypeName
   , p :: [Type]
+  , o :: Maybe Type
   } deriving (Show, Eq)
 
 instance IsString Type where
-  fromString s = Type (fromString s) []
+  fromString s = Type (fromString s) [] Nothing
 
 instance FromJSON Type where
   parseJSON = \case
-    String s -> pure $ Type (TypeName s) []
+    String s -> pure $ Type (TypeName s) [] Nothing
     Object o -> do
       n <- o .: "n"
-      case HML.lookup "p" o of
-        Nothing -> pure $ Type n []
-        Just (String p) -> pure $ Type n [Type (TypeName p) []]
-        Just p -> Type n <$> (parseJSON p)
+      case (HML.lookup "p" o, HML.lookup "o" o) of
+        (Nothing, Nothing) -> pure $ Type n [] Nothing
+        (Just (String p), Nothing) -> pure $ Type n [Type (TypeName p) [] Nothing] Nothing
+        (Just p, Nothing) -> Type n <$> (parseJSON p) <*> pure Nothing
+        (Just (String p), Just output) -> Type n [Type (TypeName p) [] Nothing] <$> (Just <$> parseJSON output)
+        (Just p, Just output) -> Type n <$> (parseJSON p) <*> (Just <$> parseJSON output)
+        _ -> mzero
     _ -> mzero
 
 instance ToJSON Type where
-  toJSON (Type n []) = toJSON n
-  toJSON (Type n [p]) = object [ "n" .= n, "p" .= toJSON p ]
-  toJSON (Type n ps) = object [ "n" .= n, "p" .= map toJSON ps ]
+  toJSON (Type n [] Nothing) = toJSON n
+  toJSON (Type n [] (Just o)) = object [ "n" .= n, "o" .= toJSON o ]
+  toJSON (Type n [p] Nothing) = object [ "n" .= n, "p" .= toJSON p ]
+  toJSON (Type n [p] (Just o)) = object [ "n" .= n, "p" .= toJSON p, "o" .= toJSON o]
+  toJSON (Type n ps Nothing) = object [ "n" .= n, "p" .= map toJSON ps ]
+  toJSON (Type n ps (Just o)) = object [ "n" .= n, "p" .= map toJSON ps, "o" .= toJSON o ]
 
 newtype TypeName = TypeName Text
   deriving (Show, Eq, Ord, FromJSON, ToJSON, IsString)
@@ -251,19 +281,19 @@
   getType _ = "F64"
 
 instance HasType a => HasType (Maybe a) where
-  getType x = Type "Option" [getType (p x)]
+  getType x = Type "Option" [getType (p x)] Nothing
     where
       p :: Proxy (Maybe a) -> Proxy a
       p _ = Proxy
 
 instance HasType a => HasType [a] where
-  getType x = Type "List" [getType (p x)]
+  getType x = Type "List" [getType (p x)] Nothing
     where
       p :: Proxy [a] -> Proxy a
       p _ = Proxy
 
 instance (HasType e, HasType a) => HasType (Either e a) where
-  getType x = Type "Either" [getType (p1 x), getType (p2 x)]
+  getType x = Type "Either" [getType (p1 x), getType (p2 x)] Nothing
     where
       p1 :: Proxy (Either e a) -> Proxy e
       p1 _ = Proxy
@@ -273,7 +303,7 @@
 --
 
 instance (HasType t1, HasType t2) => HasType (t1, t2) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x)] Nothing
      where
        p1 :: Proxy (t1, t2) -> Proxy t1
        p1 _ = Proxy
@@ -281,7 +311,7 @@
        p2 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3) => HasType (t1, t2, t3) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3) -> Proxy t1
        p1 _ = Proxy
@@ -291,7 +321,7 @@
        p3 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4) => HasType (t1, t2, t3, t4) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4) -> Proxy t1
        p1 _ = Proxy
@@ -303,7 +333,7 @@
        p4 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5) => HasType (t1, t2, t3, t4, t5) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5) -> Proxy t1
        p1 _ = Proxy
@@ -317,7 +347,7 @@
        p5 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6) => HasType (t1, t2, t3, t4, t5, t6) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6) -> Proxy t1
        p1 _ = Proxy
@@ -333,7 +363,7 @@
        p6 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7) => HasType (t1, t2, t3, t4, t5, t6, t7) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7) -> Proxy t1
        p1 _ = Proxy
@@ -351,7 +381,7 @@
        p7 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8) => HasType (t1, t2, t3, t4, t5, t6, t7, t8) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8) -> Proxy t1
        p1 _ = Proxy
@@ -371,7 +401,7 @@
        p8 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9) -> Proxy t1
        p1 _ = Proxy
@@ -393,7 +423,7 @@
        p9 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) -> Proxy t1
        p1 _ = Proxy
@@ -417,7 +447,7 @@
        p10 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11) -> Proxy t1
        p1 _ = Proxy
@@ -443,7 +473,7 @@
        p11 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12) -> Proxy t1
        p1 _ = Proxy
@@ -471,7 +501,7 @@
        p12 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13) -> Proxy t1
        p1 _ = Proxy
@@ -501,7 +531,7 @@
        p13 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14) -> Proxy t1
        p1 _ = Proxy
@@ -533,7 +563,7 @@
        p14 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15) -> Proxy t1
        p1 _ = Proxy
@@ -567,7 +597,7 @@
        p15 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16) -> Proxy t1
        p1 _ = Proxy
@@ -603,7 +633,7 @@
        p16 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17) -> Proxy t1
        p1 _ = Proxy
@@ -641,7 +671,7 @@
        p17 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18) -> Proxy t1
        p1 _ = Proxy
@@ -681,7 +711,7 @@
        p18 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19) -> Proxy t1
        p1 _ = Proxy
@@ -723,7 +753,7 @@
        p19 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19, HasType t20) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20) -> Proxy t1
        p1 _ = Proxy
@@ -767,7 +797,7 @@
        p20 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19, HasType t20, HasType t21) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21) -> Proxy t1
        p1 _ = Proxy
@@ -813,7 +843,7 @@
        p21 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19, HasType t20, HasType t21, HasType t22) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22) -> Proxy t1
        p1 _ = Proxy
@@ -861,7 +891,7 @@
        p22 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19, HasType t20, HasType t21, HasType t22, HasType t23) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23) -> Proxy t1
        p1 _ = Proxy
@@ -911,7 +941,7 @@
        p23 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19, HasType t20, HasType t21, HasType t22, HasType t23, HasType t24) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24) -> Proxy t1
        p1 _ = Proxy
@@ -963,7 +993,7 @@
        p24 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19, HasType t20, HasType t21, HasType t22, HasType t23, HasType t24, HasType t25) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25) -> Proxy t1
        p1 _ = Proxy
@@ -1017,7 +1047,7 @@
        p25 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19, HasType t20, HasType t21, HasType t22, HasType t23, HasType t24, HasType t25, HasType t26) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26) -> Proxy t1
        p1 _ = Proxy
@@ -1073,7 +1103,7 @@
        p26 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19, HasType t20, HasType t21, HasType t22, HasType t23, HasType t24, HasType t25, HasType t26, HasType t27) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x), getType (p27 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x), getType (p27 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27) -> Proxy t1
        p1 _ = Proxy
@@ -1131,7 +1161,7 @@
        p27 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19, HasType t20, HasType t21, HasType t22, HasType t23, HasType t24, HasType t25, HasType t26, HasType t27, HasType t28) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x), getType (p27 x), getType (p28 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x), getType (p27 x), getType (p28 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28) -> Proxy t1
        p1 _ = Proxy
@@ -1191,7 +1221,7 @@
        p28 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19, HasType t20, HasType t21, HasType t22, HasType t23, HasType t24, HasType t25, HasType t26, HasType t27, HasType t28, HasType t29) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x), getType (p27 x), getType (p28 x), getType (p29 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x), getType (p27 x), getType (p28 x), getType (p29 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29) -> Proxy t1
        p1 _ = Proxy
@@ -1253,7 +1283,7 @@
        p29 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19, HasType t20, HasType t21, HasType t22, HasType t23, HasType t24, HasType t25, HasType t26, HasType t27, HasType t28, HasType t29, HasType t30) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x), getType (p27 x), getType (p28 x), getType (p29 x), getType (p30 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x), getType (p27 x), getType (p28 x), getType (p29 x), getType (p30 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30) -> Proxy t1
        p1 _ = Proxy
@@ -1317,7 +1347,7 @@
        p30 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19, HasType t20, HasType t21, HasType t22, HasType t23, HasType t24, HasType t25, HasType t26, HasType t27, HasType t28, HasType t29, HasType t30, HasType t31) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, t31) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x), getType (p27 x), getType (p28 x), getType (p29 x), getType (p30 x), getType (p31 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x), getType (p27 x), getType (p28 x), getType (p29 x), getType (p30 x), getType (p31 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, t31) -> Proxy t1
        p1 _ = Proxy
@@ -1383,7 +1413,7 @@
        p31 _ = Proxy
 
 instance (HasType t1, HasType t2, HasType t3, HasType t4, HasType t5, HasType t6, HasType t7, HasType t8, HasType t9, HasType t10, HasType t11, HasType t12, HasType t13, HasType t14, HasType t15, HasType t16, HasType t17, HasType t18, HasType t19, HasType t20, HasType t21, HasType t22, HasType t23, HasType t24, HasType t25, HasType t26, HasType t27, HasType t28, HasType t29, HasType t30, HasType t31, HasType t32) => HasType (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, t31, t32) where
-  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x), getType (p27 x), getType (p28 x), getType (p29 x), getType (p30 x), getType (p31 x), getType (p32 x)]
+  getType x = Type "Tuple" [getType (p1 x), getType (p2 x), getType (p3 x), getType (p4 x), getType (p5 x), getType (p6 x), getType (p7 x), getType (p8 x), getType (p9 x), getType (p10 x), getType (p11 x), getType (p12 x), getType (p13 x), getType (p14 x), getType (p15 x), getType (p16 x), getType (p17 x), getType (p18 x), getType (p19 x), getType (p20 x), getType (p21 x), getType (p22 x), getType (p23 x), getType (p24 x), getType (p25 x), getType (p26 x), getType (p27 x), getType (p28 x), getType (p29 x), getType (p30 x), getType (p31 x), getType (p32 x)] Nothing
      where
        p1 :: Proxy (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, t31, t32) -> Proxy t1
        p1 _ = Proxy
@@ -1475,7 +1505,7 @@
   for (var i = 1; i < n; i++) {
     l = l.concat([', getType (p', i + 1, ' x)']);
   }
-  l = l.concat([']\n']);
+  l = l.concat(['] Nothing\n']);
 
 
   l = l.concat(['     where\n']);
diff --git a/library/Colorless/Val.hs b/library/Colorless/Val.hs
--- a/library/Colorless/Val.hs
+++ b/library/Colorless/Val.hs
@@ -149,10 +149,10 @@
   toVal u = Val'Prim $ Prim'U64 u
 
 instance ToVal Float where
-    toVal f = Val'Const $ Const'Number $ fromFloatDigits f
+    toVal f = Val'Prim $ Prim'F32 f
 
 instance ToVal Double where
-    toVal d = Val'Const $ Const'Number $ fromFloatDigits d
+    toVal d = Val'Prim $ Prim'F64 d
 
 instance ToVal a => ToVal (Maybe a) where
   toVal Nothing = Val'Const Const'Null
@@ -365,10 +365,12 @@
 
 instance FromVal Float where
   fromVal (Val'Const (Const'Number n)) = Just $ toRealFloat n
+  fromVal (Val'Prim (Prim'F32 f)) = Just f
   fromVal _ = Nothing
 
 instance FromVal Double where
   fromVal (Val'Const (Const'Number n)) = Just $ toRealFloat n
+  fromVal (Val'Prim (Prim'F64 f)) = Just f
   fromVal _ = Nothing
 
 instance FromVal a => FromVal (Maybe a) where
diff --git a/package.yaml b/package.yaml
--- a/package.yaml
+++ b/package.yaml
@@ -1,5 +1,5 @@
 name: colorless
-version: '2.2.17'
+version: '2.2.18'
 category: Web
 synopsis: Colorless | The Programmatic IDL
 description: Colorless | The Programmatic IDL
