diff --git a/egison.cabal b/egison.cabal
--- a/egison.cabal
+++ b/egison.cabal
@@ -1,5 +1,5 @@
 Name:                egison
-Version:             2.2.0
+Version:             2.2.1
 Synopsis:            An Interpreter for the Programming Language Egison
 Description:         An interpreter for the programming language Egison.
                      A feature of Egison is the strong pattern match facility.
diff --git a/elisp/egison-mode.el b/elisp/egison-mode.el
--- a/elisp/egison-mode.el
+++ b/elisp/egison-mode.el
@@ -1,171 +1,176 @@
-;;; egison-mode.el --- Egison editing mode
-
-(defconst egison-font-lock-keywords-1
-  (eval-when-compile
-    (list
-     "\\<define\\>"
-     "\\<test\\>"
-     "\\<execute\\>"
-     
-     "\\<lambda\\>"
-     "\\<macro\\>"
-     "\\<do\\>"
-     "\\<if\\>"
-     "\\<let\\>"
-     "\\<letrec\\>"
-     "\\<type\\>"
-     "\\<type-ref\\>"
-     "\\<destructor\\>"
-     "\\<loop\\>"
-     "\\<match\\>"
-     "\\<match-all\\>"
-
-     "\\\."
-     "\\\,"
-     "\\\!"
-     "\\\~"
-     "\\\#"
-     "|"
-     "%"
-     "\\\&"
-     "@"
-     "\\<_\\>"
-     ))
-  "Subdued expressions to highlight in Egison modes.")
-
-(defconst egison-font-lock-keywords-2
-  (append egison-font-lock-keywords-1
-   (eval-when-compile
-     (list
-      (cons "\\\$\\\w*" font-lock-variable-name-face)
-      )))
-  "Gaudy expressions to highlight in Egison modes.")
-
-(defvar egison-font-lock-keywords egison-font-lock-keywords-1
-  "Default expressions to highlight in Egison modes.")
-
-
-(defun open-paren-p ()
-  (let ((c (string-to-char (thing-at-point 'char))))
-    (or (eq c 40) (eq c 60) (eq c 91) (eq c 123))))
-
-(defun close-paren-p ()
-  (let ((c (string-to-char (thing-at-point 'char))))
-    (or (eq c 41) (eq c 62) (eq c 93) (eq c 125))))
-
-(defun last-unclosed-paren ()
-  (save-excursion
-    (let ((pc 0))
-      (while (<= pc 0)
-        (if (bobp)
-            (setq pc 2)
-          (backward-char)
-          (if (open-paren-p)
-              (progn
-                (setq pc (+ pc 1))
-                (if (and (= pc 0) (= (current-column) 0))
-                    (setq pc 2)))
-            (if (close-paren-p)
-                (setq pc (- pc 1))))))
-      (if (= pc 2)
-          nil
-        (point)))))
-
-(defun indent-point ()
-  (save-excursion
-    (beginning-of-line)
-    (let ((p (last-unclosed-paren)))
-      (if p
-          (progn
-            (goto-char (last-unclosed-paren))
-            (let ((cp (current-column)))
-              (cond  ((eq (string-to-char (thing-at-point 'char)) 40)
-                      (forward-char)
-                      (let* ((op (current-word))
-                             (ip (keyword-indent-point op)))
-                        (if ip
-                            (+ ip cp)
-                          (+ 2 (length op) cp))))
-                     ((eq (string-to-char (thing-at-point 'char)) 60)
-                      (forward-char)
-                      (let ((op (current-word)))
-                        (+ 2 (length op) cp)))
-                     (t (+ 1 cp)))))
-        0))))
-
-(defun keyword-indent-point (name)
-  (cond ((equal "define" name) 2)
-        ((equal "lambda" name) 2)
-        ((equal "macro" name) 2)
-        ((equal "let" name) 2)
-        ((equal "letrec" name) 2)
-        ((equal "match" name) 2)
-        ((equal "match-all" name) 2)
-        ((equal "type" name) 2)
-        ((equal "destructor" name) 2)
-        ))
-
-(defun egison-indent-line ()
-  "indent current line as Egison code."
-  (interactive)
-  (indent-line-to (indent-point)))
-
-
-(defvar egison-mode-map
-  (let ((smap (make-sparse-keymap)))
-    (define-key smap "\C-j" 'newline-and-indent)
-    smap)
-  "Keymap for Egison mode.")
-
-
-(defvar egison-mode-syntax-table
-  (let ((egison-mode-syntax-table (make-syntax-table)))
-    (modify-syntax-entry 60 "(" egison-mode-syntax-table)
-    (modify-syntax-entry 62 ")" egison-mode-syntax-table)
-    (modify-syntax-entry 59 "<" egison-mode-syntax-table)
-    (modify-syntax-entry 10 ">" egison-mode-syntax-table)
-    egison-mode-syntax-table)
-  ;; (copy-syntax-table lisp-mode-syntax-table)
-  "Syntax table for Egison mode")
-
-(defun egison-mode-variables ()
-  (set-syntax-table egison-mode-syntax-table)
-  (set (make-local-variable 'font-lock-defaults)
-       '((egison-font-lock-keywords
-          egison-font-lock-keywords-1 egison-font-lock-keywords-2)
-         nil t (("+-*/=?%:_" . "w") ("<" . "(") (">" . ")"))
-         ))
-  (set (make-local-variable 'indent-line-function) 'egison-indent-line)
-  (set (make-local-variable 'comment-start) ";")
-  (set (make-local-variable 'comment-end) "")
-  (set (make-local-variable 'comment-start-skip) ";+ *")
-  (set (make-local-variable 'comment-end-skip) nil)
-  )
-
-
-(defun egison-mode ()
-  "Major mode for editing Egison code.
-
-Commands:
-\\{egison-mode-map}
-Entry to this mode calls the value of `egison-mode-hook'
-if that value is non-nil."
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map egison-mode-map)
-  (setq major-mode 'egison-mode)
-  (setq mode-name "Egison")
-  (egison-mode-variables)
-  (run-mode-hooks 'egison-mode-hook))
-
-
-(defgroup egison nil
-  "Editing Egison code."
-  :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
-  :group 'lisp)
-
-(defcustom egison-mode-hook nil
-  "Normal hook run when entering `egison-mode'.
-See `run-hooks'."
-  :type 'hook
-  :group 'egison)
+;;; egison-mode.el --- Egison editing mode
+
+(defconst egison-font-lock-keywords-1
+  (eval-when-compile
+    (list
+     "\\<define\\>"
+     "\\<test\\>"
+     "\\<execute\\>"
+     
+     "\\<lambda\\>"
+     "\\<macro\\>"
+     "\\<do\\>"
+     "\\<if\\>"
+     "\\<let\\>"
+     "\\<letrec\\>"
+     "\\<type\\>"
+     "\\<type-ref\\>"
+     "\\<of\\>"
+     "\\<destructor\\>"
+     "\\<loop\\>"
+     "\\<match\\>"
+     "\\<match-all\\>"
+
+     "\\\."
+     "\\\,"
+     "\\\!"
+     "\\\~"
+     "\\\#"
+     "|"
+     "%"
+     "\\\&"
+     "@"
+     "\\<_\\>"
+     ))
+  "Subdued expressions to highlight in Egison modes.")
+
+(defconst egison-font-lock-keywords-2
+  (append egison-font-lock-keywords-1
+   (eval-when-compile
+     (list
+      (cons "\\\$\\\w*" font-lock-variable-name-face)
+      )))
+  "Gaudy expressions to highlight in Egison modes.")
+
+(defvar egison-font-lock-keywords egison-font-lock-keywords-1
+  "Default expressions to highlight in Egison modes.")
+
+
+(defun open-paren-p ()
+  (let ((c (string-to-char (thing-at-point 'char))))
+    (or (eq c 40) (eq c 60) (eq c 91) (eq c 123))))
+
+(defun close-paren-p ()
+  (let ((c (string-to-char (thing-at-point 'char))))
+    (or (eq c 41) (eq c 62) (eq c 93) (eq c 125))))
+
+(defun last-unclosed-paren ()
+  (save-excursion
+    (let ((pc 0))
+      (while (<= pc 0)
+        (if (bobp)
+            (setq pc 2)
+          (backward-char)
+          (if (open-paren-p)
+              (progn
+                (setq pc (+ pc 1))
+                (if (and (= pc 0) (= (current-column) 0))
+                    (setq pc 2)))
+            (if (close-paren-p)
+                (setq pc (- pc 1))))))
+      (if (= pc 2)
+          nil
+        (point)))))
+
+(defun indent-point ()
+  (save-excursion
+    (beginning-of-line)
+    (let ((p (last-unclosed-paren)))
+      (if p
+          (progn
+            (goto-char (last-unclosed-paren))
+            (let ((cp (current-column)))
+              (cond ((eq (string-to-char (thing-at-point 'char)) 40)
+                     (forward-char)
+                     (let* ((op (current-word))
+                            (ip (keyword-indent-point op)))
+                       (if ip
+                           (+ ip cp)
+                         (+ 2 (length op) cp))))
+                    ((eq (string-to-char (thing-at-point 'char)) 60)
+                     (forward-char)
+                     (let ((op (current-word)))
+                       (+ 2 (length op) cp)))
+                    ((eq (string-to-char (thing-at-point 'char)) 91)
+                     (forward-char)
+                     (if (eq (string-to-char (thing-at-point 'char)) 124)
+                       (+ 2 cp)))
+                    (t (+ 1 cp)))))
+        0))))
+
+(defun keyword-indent-point (name)
+  (cond ((equal "define" name) 2)
+        ((equal "lambda" name) 2)
+        ((equal "macro" name) 2)
+        ((equal "let" name) 2)
+        ((equal "letrec" name) 2)
+        ((equal "match" name) 2)
+        ((equal "match-all" name) 2)
+        ((equal "type" name) 2)
+        ((equal "destructor" name) 2)
+        ))
+
+(defun egison-indent-line ()
+  "indent current line as Egison code."
+  (interactive)
+  (indent-line-to (indent-point)))
+
+
+(defvar egison-mode-map
+  (let ((smap (make-sparse-keymap)))
+    (define-key smap "\C-j" 'newline-and-indent)
+    smap)
+  "Keymap for Egison mode.")
+
+
+(defvar egison-mode-syntax-table
+  (let ((egison-mode-syntax-table (make-syntax-table)))
+    (modify-syntax-entry 60 "(" egison-mode-syntax-table)
+    (modify-syntax-entry 62 ")" egison-mode-syntax-table)
+    (modify-syntax-entry 59 "<" egison-mode-syntax-table)
+    (modify-syntax-entry 10 ">" egison-mode-syntax-table)
+    egison-mode-syntax-table)
+  ;; (copy-syntax-table lisp-mode-syntax-table)
+  "Syntax table for Egison mode")
+
+(defun egison-mode-variables ()
+  (set-syntax-table egison-mode-syntax-table)
+  (set (make-local-variable 'font-lock-defaults)
+       '((egison-font-lock-keywords
+          egison-font-lock-keywords-1 egison-font-lock-keywords-2)
+         nil t (("+-*/=?%:_" . "w") ("<" . "(") (">" . ")"))
+         ))
+  (set (make-local-variable 'indent-line-function) 'egison-indent-line)
+  (set (make-local-variable 'comment-start) ";")
+  (set (make-local-variable 'comment-end) "")
+  (set (make-local-variable 'comment-start-skip) ";+ *")
+  (set (make-local-variable 'comment-end-skip) nil)
+  )
+
+
+(defun egison-mode ()
+  "Major mode for editing Egison code.
+
+Commands:
+\\{egison-mode-map}
+Entry to this mode calls the value of `egison-mode-hook'
+if that value is non-nil."
+  (interactive)
+  (kill-all-local-variables)
+  (use-local-map egison-mode-map)
+  (setq major-mode 'egison-mode)
+  (setq mode-name "Egison")
+  (egison-mode-variables)
+  (run-mode-hooks 'egison-mode-hook))
+
+
+(defgroup egison nil
+  "Editing Egison code."
+  :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
+  :group 'lisp)
+
+(defcustom egison-mode-hook nil
+  "Normal hook run when entering `egison-mode'.
+See `run-hooks'."
+  :type 'hook
+  :group 'egison)
diff --git a/hs-src/Language/Egison/Core.hs b/hs-src/Language/Egison/Core.hs
--- a/hs-src/Language/Egison/Core.hs
+++ b/hs-src/Language/Egison/Core.hs
@@ -135,6 +135,7 @@
 cEval (Closure env expr) = eval env expr
 cEval (Value val) = return val
 cEval (Intermidiate iVal) = iEval iVal
+cEval (Loop _ _ _ _ _) = throwError $ Default "cEval: cannot reach here: loop object cannot be evaluated"
 
 cEval1 :: Object -> IOThrowsError Object
 cEval1 (Closure _ (BoolExpr contents)) = return $ Value (Bool contents)
@@ -169,6 +170,9 @@
 cEval1 (Closure env (CollectionExpr innerExprs)) = do
   innerRefs <- liftIO $ mapM (makeInnerValRef env) innerExprs
   return $ Intermidiate $ ICollection innerRefs
+cEval1 (Closure env (ArrayExpr exprs)) = do
+  vals <- mapM (eval env) exprs
+  return $ Value $ Array $ listArray (1, (length vals)) vals
 cEval1 (Closure _ WildCardExpr) = return $ Value WildCard
 cEval1 (Closure env (PatVarExpr name numExprs)) = do
   numVals <- mapM (eval env) numExprs
@@ -945,7 +949,16 @@
               ("&&", boolBinop (&&)),
               ("||", boolBinop (||)),
 
-              ("eof?", isEgisonEOF)
+              ("eof?", isEgisonEOF),
+
+              ("array-dimension", arrayDimension),
+              ("array-size", arraySize),
+
+              ("array-ref", arrayRef),
+--              ("array-sub-ref", arrayRef),
+              
+              ("array-to-collection", arrayToCollection),
+              ("collection-to-array", collectionToArray)
 
               ]
 
diff --git a/hs-src/Language/Egison/Numerical.hs b/hs-src/Language/Egison/Numerical.hs
--- a/hs-src/Language/Egison/Numerical.hs
+++ b/hs-src/Language/Egison/Numerical.hs
@@ -5,6 +5,7 @@
 --import Data.Fixed
 --import Numeric
 --import Text.Printf
+import Data.Array
 
 boolBinop :: (Bool -> Bool -> Bool) -> [EgisonVal] -> ThrowsError EgisonVal
 boolBinop _ singleVal@[_] = throwError $ NumArgs 2 singleVal
@@ -66,42 +67,42 @@
 
 floatRound, floatFloor, floatCeiling, floatTruncate :: [EgisonVal] -> ThrowsError EgisonVal
 floatRound [(Float n)] = return $ Float $ fromInteger $ round n
-floatRound [x] = throwError $ TypeMismatch "floatber" x
+floatRound [x] = throwError $ TypeMismatch "floatber" [x]
 floatRound badArgList = throwError $ NumArgs 1 badArgList
 
 floatFloor [(Float n)] = return $ Float $ fromInteger $ floor n
-floatFloor [x] = throwError $ TypeMismatch "number" x
+floatFloor [x] = throwError $ TypeMismatch "number" [x]
 floatFloor badArgList = throwError $ NumArgs 1 badArgList
 
 floatCeiling [(Float n)] = return $ Float $ fromInteger $ ceiling n
-floatCeiling [x] = throwError $ TypeMismatch "number" x
+floatCeiling [x] = throwError $ TypeMismatch "number" [x]
 floatCeiling badArgList = throwError $ NumArgs 1 badArgList
 
 floatTruncate [(Float n)] = return $ Float $ fromInteger $ truncate n
-floatTruncate [x] = throwError $ TypeMismatch "number" x
+floatTruncate [x] = throwError $ TypeMismatch "number" [x]
 floatTruncate badArgList = throwError $ NumArgs 1 badArgList
 
 numSqrt, numExpt :: [EgisonVal] -> ThrowsError EgisonVal
 numSqrt [(Float n)] = if n >= 0 then return $ Float $ sqrt n
                                 else throwError $ Default "negative number to sqrt"
-numSqrt [x] = throwError $ TypeMismatch "number" x
+numSqrt [x] = throwError $ TypeMismatch "number" [x]
 numSqrt badArgList = throwError $ NumArgs 1 badArgList
 
 numExpt [(Number n), (Number p)] = return $ Float $ (fromInteger n) ^ p
 numExpt [(Float n), (Number p)] = return $ Float $ n ^ p
-numExpt [_, y] = throwError $ TypeMismatch "integer" y
+numExpt [_, y] = throwError $ TypeMismatch "integer" [y]
 numExpt badArgList = throwError $ NumArgs 2 badArgList
 
 numExp :: [EgisonVal] -> ThrowsError EgisonVal
 numExp [(Number n)] = return $ Float $ exp $ fromInteger n
 numExp [(Float n)] = return $ Float $ exp n
-numExp [x] = throwError $ TypeMismatch "number" x
+numExp [x] = throwError $ TypeMismatch "number" [x]
 numExp badArgList = throwError $ NumArgs 1 badArgList
 
 numLog :: [EgisonVal] -> ThrowsError EgisonVal
 numLog [(Number n)] = return $ Float $ log $ fromInteger n
 numLog [(Float n)] = return $ Float $ log n
-numLog [x] = throwError $ TypeMismatch "number" x
+numLog [x] = throwError $ TypeMismatch "number" [x]
 numLog badArgList = throwError $ NumArgs 1 badArgList
 
 -- |Convert a number to a string; radix is optional, defaults to base 10
@@ -133,28 +134,91 @@
 --  the wrong type is passed.
 unpackBool :: EgisonVal -> ThrowsError Bool
 unpackBool (Bool b) = return b
-unpackBool notBool = throwError $ TypeMismatch "bool" notBool
+unpackBool notBool = throwError $ TypeMismatch "bool" [notBool]
 
 -- |Extract an char from the given value, throwing a type error if
 --  the wrong type is passed.
 unpackChar :: EgisonVal -> ThrowsError Char
 unpackChar (Char c) = return c
-unpackChar notChar = throwError $ TypeMismatch "char" notChar
+unpackChar notChar = throwError $ TypeMismatch "char" [notChar]
 
 -- |Extract an char from the given value, throwing a type error if
 --  the wrong type is passed.
 unpackString :: EgisonVal -> ThrowsError String
 unpackString (String str) = return str
-unpackString notString = throwError $ TypeMismatch "string" notString
+unpackString notString = throwError $ TypeMismatch "string" [notString]
 
 -- |Extract an integer from the given value, throwing a type error if
 --  the wrong type is passed.
 unpackNum :: EgisonVal -> ThrowsError Integer
 unpackNum (Number n) = return n
-unpackNum notNum = throwError $ TypeMismatch "number" notNum
+unpackNum notNum = throwError $ TypeMismatch "number" [notNum]
 
 -- |Extract an double from the given value, throwing a type error if
 --  the wrong type is passed.
 unpackFloat :: EgisonVal -> ThrowsError Double
 unpackFloat (Float n) = return n
-unpackFloat notFloat = throwError $ TypeMismatch "float" notFloat
+unpackFloat notFloat = throwError $ TypeMismatch "float" [notFloat]
+
+
+---------------------------------------------------
+-- Array
+---------------------------------------------------
+
+arrayDimension :: [EgisonVal] -> ThrowsError EgisonVal
+arrayDimension [val] = helper 0 val
+ where helper d (Array arr) =
+         let xs = elems arr in
+         case xs of
+           [] -> return $ Number (d + 1)
+           (e:_) -> case e of
+                      Array _ -> helper (d + 1) e
+                      _ -> return $ Number (d + 1)
+       helper d _ = return $ Number d
+arrayDimension badArgList = throwError $ NumArgs 1 badArgList
+
+arraySize :: [EgisonVal] -> ThrowsError EgisonVal
+arraySize [(Number n), val@(Array _)] = helper n val
+ where helper 1 (Array arr) = return $ Number $ fromIntegral $ length $ indices arr
+       helper n2 (Array arr) =
+         if n2 > 1
+           then let xs = elems arr in
+                  case xs of
+                    (e:_) -> case e of
+                               Array _ -> helper (n2 - 1) e
+                               _ -> throwError $ Default "arraySize: larger dimention size than actual"
+                    _ -> throwError $ Default "arraySize: larger dimention size than actual"
+           else throwError $ Default "arraySize: dimention size must be more than 1"
+       helper _ _ = throwError $ Default "arraySize: type mismatch"
+arraySize [x, y] = throwError $ TypeMismatch "number, array" [x, y]
+arraySize badArgList = throwError $ NumArgs 2 badArgList
+
+arrayRef :: [EgisonVal] -> ThrowsError EgisonVal
+arrayRef [tuple, val@(Array _)] = do ns <- mapM unpackNum $ tupleToList tuple
+                                     helper ns val
+ where helper [n] (Array arr) = return (arr ! (fromIntegral n))
+       helper (n:ns) (Array arr) =
+         if n > 0
+           then let e = arr ! (fromIntegral n) in
+                  case e of
+                    Array _ -> helper ns e
+                    _ -> throwError $ Default "arraySize: larger dimention size than actual"
+           else throwError $ Default "arrayRef: index number should be more than 0"
+       helper _ _ = throwError $ Default "arraySize: type mismatch"
+arrayRef [x, y] = throwError $ TypeMismatch "tuple of number, array" [x, y]
+arrayRef badArgList = throwError $ NumArgs 2 badArgList
+
+arrayToCollection :: [EgisonVal] -> ThrowsError EgisonVal
+arrayToCollection [val@(Array _)] = helper val
+ where helper (Array arr) = do es <- mapM helper $ elems arr
+                               return $ Collection (map Element es)
+       helper val2 = return val2
+arrayToCollection [x] = throwError $ TypeMismatch "array" [x]
+arrayToCollection badArgList = throwError $ NumArgs 1 badArgList
+
+collectionToArray :: [EgisonVal] -> ThrowsError EgisonVal
+collectionToArray [(Collection innerVals)] =
+  let vals = innerValsToList innerVals in
+    return $ Array $ listArray (1, (length vals)) vals
+collectionToArray [x] = throwError $ TypeMismatch "collection" [x]
+collectionToArray badArgList = throwError $ NumArgs 1 badArgList
diff --git a/hs-src/Language/Egison/Parser.hs b/hs-src/Language/Egison/Parser.hs
--- a/hs-src/Language/Egison/Parser.hs
+++ b/hs-src/Language/Egison/Parser.hs
@@ -51,7 +51,7 @@
 
 symbol :: Parser Char
 --symbol = oneOf "!$%&|*+-/:<=>?@^_~."
-symbol = oneOf "%&|*+-/:="
+symbol = oneOf "&*+-/:="
 
 symbol2 :: Parser Char
 --symbol = oneOf "!$%&|*+-/:<=>?@^_~."
@@ -269,6 +269,13 @@
                                     return (name, expr)))
                       whiteSpace)
 
+--parseTypeRefExpr :: Parser EgisonExpr
+--parseTypeRefExpr = do
+--  typExpr <- parseExpr
+--  char '.'
+--  name <- lexeme identifier
+--  return $ TypeRefExpr typExpr name
+
 parseVar :: Parser EgisonExpr
 parseVar = do name <- identifier
               nums <- lexeme parseIndexNums
@@ -396,6 +403,10 @@
   <|> lexeme parsePatVarOmitExpr
   <|> lexeme parseVarOmitExpr
   <|> lexeme parseVar
+  <|> do try (lexeme (string "[|"))
+         exprs <- sepEndBy parseExpr whiteSpace
+         (lexeme (string "|]"))
+         return (ArrayExpr exprs)
   <|> angles (do cons <- lexeme identifier
                  argExprs <- sepEndBy parseExpr whiteSpace
                  return $ InductiveDataExpr cons argExprs)
@@ -433,6 +444,10 @@
           <|> do try (string "type-ref" >> many1 space)
                  typExpr <- lexeme parseExpr
                  name <- lexeme identifier
+                 return (TypeRefExpr typExpr name)
+          <|> do try (string "of" >> many1 space)
+                 name <- lexeme identifier
+                 typExpr <- lexeme parseExpr
                  return (TypeRefExpr typExpr name)
           <|> do try (string "type" >> many1 space)
                  bindings <- lexeme parseRecursiveBindings
diff --git a/hs-src/Language/Egison/Primitives.hs b/hs-src/Language/Egison/Primitives.hs
--- a/hs-src/Language/Egison/Primitives.hs
+++ b/hs-src/Language/Egison/Primitives.hs
@@ -236,3 +236,4 @@
 innerExprToInnerVal :: InnerExpr -> ThrowsError InnerVal
 innerExprToInnerVal (ElementExpr expr) = exprToVal expr >>= return . Element
 innerExprToInnerVal (SubCollectionExpr expr) = exprToVal expr >>= return . SubCollection
+
diff --git a/hs-src/Language/Egison/Types.hs b/hs-src/Language/Egison/Types.hs
--- a/hs-src/Language/Egison/Types.hs
+++ b/hs-src/Language/Egison/Types.hs
@@ -2,7 +2,7 @@
 
 import Control.Monad.Error
 import Data.Complex()
-import Data.Array()
+import Data.Array
 import Data.Dynamic()
 import Data.IORef
 import qualified Data.Map
@@ -14,7 +14,7 @@
 -- Error
 --
 data EgisonError = NumArgs Integer [EgisonVal]
-  | TypeMismatch String EgisonVal
+  | TypeMismatch String [EgisonVal]
   | Parser ParseError
   | BadSpecialForm String [EgisonVal]
   | NotFunction String String
@@ -28,7 +28,7 @@
 showError (NumArgs expected found) = "Expected " ++ show expected
                                   ++ " args; found values " ++ unwordsList found
 showError (TypeMismatch expected found) = "Invalid type: expected " ++ expected
-                                  ++ ", found " ++ show found
+                                  ++ ", found " ++ unwordsList found
 showError (Parser parseErr) = "Parse error at " ++ ": " ++ show parseErr
 showError (BadSpecialForm message args) = message ++ ": " ++ unwordsList args
 showError (NotFunction message func) = message ++ ": " ++ show func
@@ -98,6 +98,7 @@
   | InductiveDataExpr String [EgisonExpr]
   | TupleExpr [InnerExpr]
   | CollectionExpr [InnerExpr]
+  | ArrayExpr [EgisonExpr]
   | FuncExpr Args EgisonExpr
   | MacroExpr [String] EgisonExpr
   | LoopExpr String String EgisonExpr EgisonExpr EgisonExpr
@@ -172,6 +173,7 @@
   | InductiveData String [EgisonVal]
   | Tuple [InnerVal]
   | Collection [InnerVal]
+  | Array (Array Int EgisonVal)
   | Type Frame
   | Destructor DestructInfo
   | Func Args EgisonExpr Env
@@ -417,6 +419,7 @@
 showVal (InductiveData cons args) = "<" ++ cons ++ " " ++ unwordsList args ++ ">"
 showVal (Tuple innerVals) = "[" ++ showInnerVals innerVals ++ "]"
 showVal (Collection innerVals) = "{" ++ showInnerVals innerVals ++ "}"
+showVal (Array _) = "#<array>"
 showVal (Type _) = "#<type>"
 showVal (Destructor _) = "#<destructor>"
 showVal (Func _ _ _) = "(lambda [" ++ "..." ++ "] ...)"
diff --git a/lib/poker-hands.egi b/lib/poker-hands.egi
--- a/lib/poker-hands.egi
+++ b/lib/poker-hands.egi
@@ -19,14 +19,7 @@
          [<diamond> []
           {[<diamond> {[]}]
            [_ {}]}]})]
-     [$=
-      (lambda [$val $tgt]
-        (match [val tgt] [Suit Suit]
-          {[[<spade> <spade>] #t]
-           [[<heart> <heart>] #t]
-           [[<club> <club>] #t]
-           [[<diamond> <diamond>] #t]
-           [[_ _] #f]}))]}))
+     [$= eq?]}))
 
 (define $Mod
   (lambda [$m]
@@ -38,7 +31,7 @@
             {[$tgt (if (= tgt n)
                        {[]}
                        {})]}]})]
-       [$= (lambda [$val $tgt] (eq? (mod val m) (mod tgt m)))]})))
+       [$= (lambda [$val $tgt] (eq-n? (mod val m) (mod tgt m)))]})))
 
 (define $Card
   (type
