简体   繁体   English

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

[英]Haskell Snap: Executing an IO action within a handler?

Say, I have a random DB function in my separate DB.hs file. 说,我在单独的DB.hs文件中有一个随机DB函数。 Something like this: 像这样:

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 ()

Now, how do I execute this functions within my handler in Site.hs if I import my DB.hs? 现在,如果导入DB.hs,如何在Site.hs的处理程序中执行此功能?

If I simply stick it in my handler like this(this is just an example): 如果我只是像这样将其粘贴在我的处理程序中(这只是一个示例):

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
             }

This does not work. 这是行不通的。 I dont want the handler to return anything, I just want it to save the Person and not return/render anything. 我不希望处理程序返回任何东西,我只希望它保存Person而不返回/呈现任何东西。

What is the correct way of doing it? 正确的做法是什么?

Thanks. 谢谢。

Your problem seems to be that you do not understand what the unit type and value are about. 您的问题似乎是您不了解单位类型和值的含义。

The unit type is a special built-in type called "()", which has exactly one value, also called "()". 单元类型是一种特殊的内置类型,称为“()”,它只有一个值,也称为“()”。

So for instance I can create a list of 4 units, which is of type "list of units". 因此,例如,我可以创建一个包含4个单位的列表,其类型为“单位列表”。

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

The unit type is used where we don't want to have any other information. 单位类型用于不需要其他信息的地方。 So technically the type "IO ()" is the type of an IO action that gives the unit value. 因此,从技术上讲,类型“ IO()”是给出单位值的IO操作的类型。

A "do" clause unsugars to a chain of ">>=" invocations. “ do”子句不包含“ >> =“调用链。 ">>=" has the type “ >> =”具有类型

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

In other words, the type of a "do" clause is the type returned by its last action. 换句话说,“ do”子句的类型是其最后一个操作返回的类型。

So where you say 所以你在哪里说

savePerson p
return ()

the "return ()" is spurious because it has exactly the same type as "savePerson p". “ return()”是虚假的,因为它的类型与“ savePerson p”完全相同。

Remember that "return" has nothing to do with flow of control: it is merely a function with the type 请记住,“返回”与控制流无关:它只是具有类型的函数

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

It would have been better called "wrap" or "inject" or something similar to avoid this confusion. 最好将其称为“包装”或“注入”或类似的名称以避免这种混淆。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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