Как Скотти делает Аппликативный конструктор
{-# 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)
Вы можете заметить, что последняя часть кода использует аппликативную функцию для создания записи, может кто-нибудь объяснить, почему она не должна создаваться как обычно?
1 ответ
Решение
Это потому что 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)
но аппликативный синтаксис легче читать.