diff --git a/hoe.cabal b/hoe.cabal
--- a/hoe.cabal
+++ b/hoe.cabal
@@ -1,5 +1,5 @@
 Name:                hoe
-Version:             1.0
+Version:             1.0.1
 Synopsis:            hoe: Haskell One-liner Evaluator
 
 Description:
@@ -22,6 +22,8 @@
 
 Executable hoe
   Main-is:             HOE.hs
+
+  Other-Modules:       Evaluator
 
   Build-depends:       base        >= 4.7 && < 5
                      , cmdargs
diff --git a/src/Evaluator.hs b/src/Evaluator.hs
new file mode 100644
--- /dev/null
+++ b/src/Evaluator.hs
@@ -0,0 +1,59 @@
+module Evaluator (
+  Script,
+  Evaluator,
+  evals
+  ) where
+
+import           Language.Haskell.Interpreter
+
+type Script    = String -> IO String
+type Evaluator = String -> Interpreter Script
+
+types :: Bool -> [(String, String, String, String)]
+types isInput
+  | isInput = ss ++ reverse (vs "Read r")
+  | otherwise = reverse ss ++ reverse (vs "Show s")
+  where
+    ss =
+      [ ("String", "string", "id", "id")
+      , ("[String]", "lines", "lines", "unlines")
+      , ("[[String]]", "table", "map words . lines", "unlines . map unwords")
+      ]
+    vs t =
+      [ (t, "value", "read", "(++ \"\\n\") . show")
+      , ("[" ++ t ++ "]", "value lines", "map read . lines", "unlines . map show")
+      , ("[[" ++ t ++ "]]", "value table", "map (map read . words) . lines", "unlines . map (unwords . map show)")
+      ]
+
+evals :: [(String, String, Evaluator)]
+evals =
+  [ evaluator "IO ()" "execute action"
+      (\expr -> "\\_ -> " ++ expr ++ " >>= \\() -> return \"\"")
+  , evaluator "Char -> Char" "map input string"
+      (\expr -> "return . map " ++ expr)
+  ] ++
+  [ evaluator outputType ("output " ++ outputDescr)
+      (\expr -> "\\_ -> return . " ++ outputCode ++ " $ " ++ expr)
+  | (outputType, outputDescr, _, outputCode) <- types False
+  ] ++
+  [ evaluator ("IO " ++ outputType) ("output result" ++ outputDescr)
+      (\expr -> "\\_ -> return . " ++ outputCode ++ " =<< " ++ expr)
+  | (outputType, outputDescr, _, outputCode) <- types False
+  ] ++
+  [ evaluator
+      (inputType ++ " -> " ++ outputType)
+      ("transform " ++ inputDescr ++ " to " ++ outputDescr)
+      (\expr -> "return . " ++ outputCode ++ " . " ++ expr ++ " . " ++ inputCode)
+  | (inputType,  inputDescr,  inputCode, _)  <- types True
+  , (outputType, outputDescr, _, outputCode) <- types False
+  ] ++
+  [ ( "a", "error", evalErr ) ]
+
+evaluator :: String -> String -> (String -> String) -> (String, String, Evaluator)
+evaluator typ description templ =
+  (typ, description, \expr -> interpret (templ $ "(" ++ expr ++ ")") (as :: Script))
+
+evalErr :: Evaluator
+evalErr expr = do
+  typ <- typeOf expr
+  fail $ "cannot evaluate type of: " ++ typ
