简体   繁体   中英

Haskell Snap: Executing an IO action within a handler?

Say, I have a random DB function in my separate DB.hs file. 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?

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.

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".

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.

A "do" clause unsugars to a chain of ">>=" invocations. ">>=" 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.

So where you say

savePerson p
return ()

the "return ()" is spurious because it has exactly the same type as "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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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