说,我在单独的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而不返回/渲染任何东西。
这样做的正确方法是什么?
感谢。
答案 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
最好将其称为“换行”或“注入”或类似的东西以避免这种混淆。