繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM