eval (Call fn args) = do
  fn' <- eval fn
  args' <- evalList args []
  case fn' of
    (HFun f) -> callHFun $ f args'
    (HIOFun f) -> callHIOFun $ f args'
    _ -> return Nil
  where
    callHFun r = do 
      case r of
        Left err -> throwError err
        Right val -> return val
    callHIOFun f = do
      r <- liftIO f
      case r of
        Left err -> throwError err
        Right val -> return val

-- Table subscript
eval (Call fn args) = do
  fn' <- eval fn
  args' <- evalList args []
  case fn' of
    (HFun f) -> callHFun $ f args'
    (HIOFun f) -> callHIOFun $ f args'
    _ -> return Nil
  where
    callHFun r = do 
      case r of
        Left err -> throwError err
        Right val -> return val
    callHIOFun f = do
      r <- liftIO f
      case r of
        Left err -> throwError err
        Right val -> return val

-- Table subscript
eval (Call fn args) = do
  fn' <- eval fn
  args' <- evalList args []
  case fn' of
    (HFun f) -> callHFun $ f args'
    (HIOFun f) -> callHIOFun $ f args'
    _ -> return Nil
  where
    callHFun r = do 
      case r of
        Left err -> throwError err
        Right val -> return val
    callHIOFun f = do
      r <- liftIO f
      case r of
        Left err -> throwError err
        Right val -> return val

-- Table subscript