Scotty 如何制作 Applicative 构造函数
How Scotty make an Applicative constructor
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative
import Data.Monoid
import Data.String
import Network.Wai.Middleware.RequestLogger
import Web.Scotty
data FullName = FullName { firstName :: String, lastName :: String }
lastFirst :: FullName -> String
lastFirst fn = lastName fn ++ ", " ++ firstName fn
main = scotty 3000 $ do
middleware logStdoutDev
get "/lastfirst/:fn/:ln" $ do
fullName <- FullName <$> param "fn" <*> param "ln"
html $ fromString (lastFirst fullName)
您可能注意到代码的最后一部分使用应用函数构造记录,有人可以解释为什么不应该像往常一样创建它吗?
这是因为 param "fn"
不是 一个 String
,而是一个 ActionM
产生一个 String
。我们不想将动作存储在 FullName
中,我们想要 运行 动作,获取其结果并将其存储。
我们可以运行如下操作
get "/lastfirst/:fn/:ln" $ do
fn <- param "fn"
ln <- param "ln"
let fullName = FullName fn ln
html $ fromString (lastFirst fullName)
但应用语法更易于阅读。
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative
import Data.Monoid
import Data.String
import Network.Wai.Middleware.RequestLogger
import Web.Scotty
data FullName = FullName { firstName :: String, lastName :: String }
lastFirst :: FullName -> String
lastFirst fn = lastName fn ++ ", " ++ firstName fn
main = scotty 3000 $ do
middleware logStdoutDev
get "/lastfirst/:fn/:ln" $ do
fullName <- FullName <$> param "fn" <*> param "ln"
html $ fromString (lastFirst fullName)
您可能注意到代码的最后一部分使用应用函数构造记录,有人可以解释为什么不应该像往常一样创建它吗?
这是因为 param "fn"
不是 一个 String
,而是一个 ActionM
产生一个 String
。我们不想将动作存储在 FullName
中,我们想要 运行 动作,获取其结果并将其存储。
我们可以运行如下操作
get "/lastfirst/:fn/:ln" $ do
fn <- param "fn"
ln <- param "ln"
let fullName = FullName fn ln
html $ fromString (lastFirst fullName)
但应用语法更易于阅读。