[英]Haskell Snap: Executing an IO action within a handler?
说,我在单独的DB.hs文件中有一个随机DB函数。 像这样:
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而不返回/呈现任何东西。
正确的做法是什么?
谢谢。
您的问题似乎是您不了解单位类型和值的含义。
单元类型是一种特殊的内置类型,称为“()”,它只有一个值,也称为“()”。
因此,例如,我可以创建一个包含4个单位的列表,其类型为“单位列表”。
fourUnits :: [()]
fourUnits = [(), (), (), ()]
单位类型用于不需要其他信息的地方。 因此,从技术上讲,类型“ IO()”是给出单位值的IO操作的类型。
“ do”子句不包含“ >> =“调用链。 “ >> =”具有类型
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b
换句话说,“ do”子句的类型是其最后一个操作返回的类型。
所以你在哪里说
savePerson p
return ()
“ return()”是虚假的,因为它的类型与“ savePerson p”完全相同。
请记住,“返回”与控制流无关:它只是具有类型的函数
return :: (Monad m) => a -> m a
最好将其称为“包装”或“注入”或类似的名称以避免这种混淆。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.