Как Скотти делает Аппликативный конструктор

{-# 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)

но аппликативный синтаксис легче читать.

Другие вопросы по тегам