Haskell Snap:在处理程序中执行IO操作?

时间:2012-03-25 03:43:35

标签: haskell haskell-snap-framework

说,我在单独的DB.hs文件中有一个随机数据库函数。 像这样:

savePerson :: Person -> IO ()
  savePerson p = do
  c <- connect
  run c "INSERT INTO persons (name, age) \
        \VALUES (?, ?)"
        [toSql (personName p), toSql (personAge p)]
  commit c
  disconnect c
  return ()

现在,如果我导入我的DB.hs,如何在Site.hs的处理程序中执行此函数?

如果我只是将它贴在我的处理程序中(这只是一个例子):

insertPerson = do
  par <- getPostParams
  let p = toPerson par
  savePerson p
  return ()
  where
    toPerson m =
      Person {personName = head (m ! (B.pack "name"))
             ,personAge  = read (B.unpack (head (m ! (B.pack "age")))) :: Int
             }

这不起作用。我不希望处理程序返回任何东西,我只是希望它保存Person而不返回/渲染任何东西。

这样做的正确方法是什么?

感谢。

1 个答案:

答案 0 :(得分:1)

你的问题似乎是你不明白单位类型和价值是什么。

单位类型是一种称为“()”的特殊内置类型,它只有一个值,也称为“()”。

例如,我可以创建一个包含4个单位的列表,其类型为“单位列表”。

fourUnits :: [()]
fourUnits = [(), (), (), ()]

在我们不想要任何其他信息的地方使用单位类型。因此从技术上讲,类型“IO()”是给出单位值的IO动作的类型。

“do”子句取消引用“&gt;&gt; =”调用链。 “&gt;&gt; =”具有类型

(>>=) :: (Monad m) => m a -> (a -> m b) -> m b

换句话说,“do”子句的类型是其最后一个操作返回的类型。

所以你说的是

savePerson p
return ()

“return()”是假的,因为它与“savePerson p”的类型完全相同。

请记住,“return”与控制流无关:它只是一个类型为

的函数
return :: (Monad m) => a -> m a

最好将其称为“换行”或“注入”或类似的东西以避免这种混淆。