Haskell Yesod 网络表单到 Sqlite3

Haskell Yesod web-form to Sqlite3

正在寻找一种方法来获取从网络表单收集的信息:

getInputR :: Handler Html
getInputR = do 
  person <- runInputGet $ Person 
            <$>ireq textField "name"
            <*>ireq intField "age" 
  defaultLayout [whamlet|<p>#{show person}|]

进入 Sqlite3:

sqliteInsertEntry :: String -> Integer -> IO () 
sqliteInsertEntry name age = do 
  conn <- connectSqlite3 "sqlite.db"
  run conn "INSERT INTO persons (Person,Age) VALUES (?, ?) "
    [ toSql ("Name" :: String)
    , toSql (35 :: Integer)
    ]
  commit conn
  disconnect conn

但我似乎无法摆脱 Handler Html

完整代码:

{-# LANGUAGE EmptyDataDecls                 #-}
{-# LANGUAGE FlexibleContexts              #-}
{-# LANGUAGE GADTs                          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving    #-}
{-# LANGUAGE MultiParamTypeClasses         #-}
{-# LANGUAGE OverloadedStrings             #-}
{-# LANGUAGE QuasiQuotes                   #-}
{-# LANGUAGE TemplateHaskell               #-}
{-# LANGUAGE TypeFamilies                  #-}

module Main where
import Yesod 
import Data.Text (Text) 
import Control.Applicative 
import Database.SQLite.Simple 
import Database.HDBC.Sqlite3
import Database.HDBC
import System.IO
import Data.List

data App = App

mkYesod "App" [parseRoutes|
  /       HomeR   GET 
  /input  InputR  GET
|]

instance Yesod App 

instance RenderMessage App FormMessage where 
  renderMessage _ _ = defaultFormMessage 

data Person = Person { 
    personName :: Text 
  , personAge  :: Int 
} deriving Show 

getHomeR :: Handler Html 
getHomeR = defaultLayout 
  [whamlet| 
    <form action=@{InputR}>
      <p>My name is 
      <input type=text name=name>
      and I am 
      <input type=text name=age>
      <input type=submit value="Introduce myself"> 
  |]

getInputR :: Handler Html
getInputR = do 
  person <- runInputGet $ Person 
            <$>ireq textField "name"
            <*>ireq intField "age" 
  defaultLayout [whamlet|<p>#{show person}|]

sqliteInsertEntry :: String -> Integer -> IO () 
sqliteInsertEntry name age = do 
  conn <- connectSqlite3 "sqlite.db"
  run conn "INSERT INTO persons (Person,Age) VALUES (?, ?) "
    [ toSql ("Name" :: String)
    , toSql (35 :: Integer)
    ]
  commit conn
  disconnect conn

fromPerson whois = print $ whois 

runWarp :: IO () 
runWarp = warp 666 App 

main :: IO ()
main = runWarp

注意:仍在学习中,但想真正开始使用 Haskell。

如果你查看 the definition of Handler,你会看到它有一个 MonadIO 的实例,所以如果你想在其中执行一个 IO 动作,你只需要至 liftIO 它:

getInputR :: Handler Html
getInputR = do 
  person <- runInputGet $ Person 
            <$>ireq textField "name"
            <*>ireq intField "age" 
  liftIO $ sqliteInsertEntry (personName person) (personAge person)
  defaultLayout [whamlet|<p>Saved!|]