diff --git a/csound-expression-dynamic.cabal b/csound-expression-dynamic.cabal
--- a/csound-expression-dynamic.cabal
+++ b/csound-expression-dynamic.cabal
@@ -1,5 +1,5 @@
 Name:          csound-expression-dynamic
-Version:       0.3.6
+Version:       0.3.7
 Cabal-Version: >= 1.22
 License:       BSD3
 License-file:  LICENSE
diff --git a/src/Csound/Dynamic/Build.hs b/src/Csound/Dynamic/Build.hs
--- a/src/Csound/Dynamic/Build.hs
+++ b/src/Csound/Dynamic/Build.hs
@@ -11,7 +11,7 @@
     -- * Constructors
     -- | Basic constructors
     prim, opcPrefix, oprPrefix, oprInfix,
-    numExp1, numExp2,
+    numExp1,
     tfm, tfmNoInlineArgs, pn, withInits,
     double, int, str, verbatim, instrIdE,
     inlineVar, gInit, gInitDouble,
@@ -132,9 +132,6 @@
 
 numExp1 :: NumOp -> E -> E
 numExp1 op x = noRate $ ExpNum $ fmap toPrimOr $ PreInline op [x]
-
-numExp2 :: NumOp -> E -> E -> E
-numExp2 op a b = noRate $ ExpNum $ fmap toPrimOr $ PreInline op [a, b]
 
 opcsArr :: Monad m => IsArrInit -> Var -> Name -> Spec1 -> [E] -> DepT m ()
 opcsArr isArrInit out name signature = tfmArr isArrInit out (opcPrefix name $ spec1 signature)
diff --git a/src/Csound/Dynamic/Render/Instr.hs b/src/Csound/Dynamic/Render/Instr.hs
--- a/src/Csound/Dynamic/Render/Instr.hs
+++ b/src/Csound/Dynamic/Render/Instr.hs
@@ -170,6 +170,7 @@
     Tfm i xs -> Tfm i $ mergeWithPrimOr (ratesFromSignature curRate (infoSignature i)) xs
     Select rate pid a -> Select rate pid (fmap (ratedVar Xr) a)
     If p t e -> If (rec2 condRate p) (rec1 curRate t) (rec1 curRate e)
+    ExpNum _ | curRate == Ar || curRate == Xr -> rec2 Xr expr
     ExpNum _ -> rec2 curRate expr
 
     ReadVar v -> ReadVar v
diff --git a/src/Csound/Dynamic/Tfm/DeduceTypes.hs b/src/Csound/Dynamic/Tfm/DeduceTypes.hs
--- a/src/Csound/Dynamic/Tfm/DeduceTypes.hs
+++ b/src/Csound/Dynamic/Tfm/DeduceTypes.hs
@@ -1,5 +1,5 @@
 module Csound.Dynamic.Tfm.DeduceTypes(
-    Var(..), TypeGraph(..), Convert(..), Stmt, deduceTypes    
+    Var(..), TypeGraph(..), Convert(..), Stmt, deduceTypes
 ) where
 
 import Data.List(nub)
@@ -26,14 +26,14 @@
 getTypes n arr = readArray arr n
 
 -- | Typed variable.
-data Var a = Var 
+data Var a = Var
     { varId   :: Int
-    , varType :: a 
+    , varType :: a
     } deriving (Show, Eq, Ord)
 
-data GetType ty     
-    = NoConversion ty 
-    -- If there is a conversion we look for a fresh identifier by map 
+data GetType ty
+    = NoConversion ty
+    -- If there is a conversion we look for a fresh identifier by map
     -- (map converts mismatched type to fresh identifier)
     | ConversionLookup (Var ty) (M.Map ty Int)
 
@@ -42,24 +42,24 @@
 lookupVar :: (Show a, Ord a) => TypeMap a -> Var a -> Var a
 lookupVar m (Var i r) = case m IM.! i of
     NoConversion     ty        -> Var i ty
-    ConversionLookup noConv f  -> maybe noConv (flip Var r) $ M.lookup r f 
+    ConversionLookup noConv f  -> maybe noConv (flip Var r) $ M.lookup r f
 
 -- Statement: assignment, like
 --    leftHandSide = RightHandSide( arguments )
 type Stmt f a = (a, f a)
 
--- When we haave type collisions we have to insert converters:
+-- When we have type collisions we have to insert converters:
 data Convert a = Convert
     { convertFrom   :: Var a
     , convertTo     :: Var a }
 
-data Line f a = Line 
-    { lineType      :: (Int, GetType a) 
-    , lineStmt      :: Stmt f (Var a) 
+data Line f a = Line
+    { lineType      :: (Int, GetType a)
+    , lineStmt      :: Stmt f (Var a)
     , lineConverts  :: [Convert a] }
 
 -- Algorithm specification for the given functor 'f' and type labels of 'a'.
-data TypeGraph f a = TypeGraph 
+data TypeGraph f a = TypeGraph
     -- create a type conversion statement
     { mkConvert   :: Convert a -> Stmt f (Var a)
     -- for a given statement and a list of requested types for the output produces a pair of
@@ -72,20 +72,20 @@
 -- deduceTypes (functorSpecificFuns) (dag) = (dagWithTypes, lastFreshIdentifier)
 --
 -- Assumption -- dag is labeled with integers. Labels are unique
--- and a list of labels is a range (0, n) (It's just what we get with CSE algorithm). 
--- 
--- Algorithm proceeds as follows. We init an array of type requests and a reference for fresh identifiers. 
+-- and a list of labels is a range (0, n) (It's just what we get with CSE algorithm).
+--
+-- Algorithm proceeds as follows. We init an array of type requests and a reference for fresh identifiers.
 -- Type request comes from right hand side of the statement. We need fresh identifiers for converters.
 -- If we are going to use a new statement for conversion we need new variables.
--- 
+--
 -- (discussLine)
 -- Then we process lines in reverse order and collect type requests by looking at right hand sides
--- and writing type requests for all arguments. 
+-- and writing type requests for all arguments.
 --
 -- (processLine)
 -- In the second run we substitute all identifiers with typed variables. It's no so strightforward
 -- due to converters. If there are converters we have to insert new statements and substitute identifiers
--- with new ones. That's why we convert variables to variables in the processLine. 
+-- with new ones. That's why we convert variables to variables in the processLine.
 --
 deduceTypes :: (Show a, Ord a, T.Traversable f) => TypeGraph f a -> [Stmt f Int] -> ([Stmt f (Var a)], Int)
 deduceTypes spec as = runST $ do
@@ -97,7 +97,7 @@
     return (reverse $ processLine typeMap =<< lines', lastId)
     where n = succ $ if (null as) then 0 else (fst $ last as)
           processLine typeMap line = fmap (mkConvert spec) (lineConverts line) ++ [(a, fmap (lookupVar typeMap) b)]
-              where (a, b) = lineStmt line            
+              where (a, b) = lineStmt line
 
 discussLine :: (Ord a, T.Traversable f) => TypeGraph f a -> TypeRequests s a -> STRef s Int -> Stmt f Int -> ST s (Line f a)
 discussLine spec typeRequests freshIds stmt@(pid, _) = do
@@ -108,17 +108,17 @@
     return $ Line (pid, getType) expr' convs
 
 mkGetType :: Ord a => [a] -> Var a -> STRef s Int -> ST s (GetType a, [Convert a])
-mkGetType typesToConvert curVar freshIds 
+mkGetType typesToConvert curVar freshIds
     | null typesToConvert = return (NoConversion $ varType curVar, [])
     | otherwise = do
         ids <- nextIds n freshIds
-        return (ConversionLookup curVar $ M.fromList (zip typesToConvert ids), 
+        return (ConversionLookup curVar $ M.fromList (zip typesToConvert ids),
                 zipWith (\i t -> Convert curVar (Var i t)) ids typesToConvert)
-    where n = length typesToConvert    
+    where n = length typesToConvert
 
 nextIds :: Int -> STRef s Int -> ST s [Int]
 nextIds n ref = do
     curId <- readSTRef ref
-    writeSTRef ref (curId + n)    
+    writeSTRef ref (curId + n)
     return [curId .. n + curId]
 
diff --git a/src/Csound/Dynamic/Types/Exp.hs b/src/Csound/Dynamic/Types/Exp.hs
--- a/src/Csound/Dynamic/Types/Exp.hs
+++ b/src/Csound/Dynamic/Types/Exp.hs
@@ -39,6 +39,7 @@
 import Data.Fix
 import Data.Eq.Deriving
 import Data.Ord.Deriving
+import Text.Show.Deriving
 import Data.Hashable.Lifted
 
 import qualified Csound.Dynamic.Tfm.DeduceTypes as R(Var(..))
@@ -410,6 +411,12 @@
 $(deriveOrd1 ''Inline)
 $(deriveOrd1 ''MainExp)
 $(deriveOrd1 ''RatedExp)
+
+$(deriveShow1 ''PrimOr)
+$(deriveShow1 ''PreInline)
+$(deriveShow1 ''Inline)
+$(deriveShow1 ''MainExp)
+$(deriveShow1 ''RatedExp)
 
 --------------------------------------------------------------
 -- comments
