[英]LiftIO, do block, and syntax
I'm getting to grips with writing an API in Haskell using Scotty. 我正在努力使用Scotty在Haskell中编写API。 My files are provided below.
我的文件在下面提供。 My questions are:
我的问题是:
In the routes definition, I'm extracting from liftIO whatsTheTime in a do block. 在路由定义中,我从liftIO中的do块中提取whatsTheTime。 This works, but it seems verbose.
这可行,但似乎很冗长。 Is there a nicer syntax?
有更好的语法吗?
In the whatsTheTime definition, I'm needing to do fromString. 在whatsTheTime定义中,我需要执行fromString。 I'd have thought OverloadedString would take care of that, but that's not the case.
我以为OverloadedString会解决这个问题,但事实并非如此。 I'd really appreciate it if somebody pointed out why it doesn't work without fromString.
如果有人指出为什么没有fromString不能使用它,我将非常感激。
In a stack project, if I need a directive like OverloadedStrings, do I need to include it every file that needs it, or just at the top of the main entrypoint? 在堆栈项目中,如果我需要诸如OverloadedStrings之类的指令,是否需要在每个需要它的文件中都包含它,或者仅将其包含在主入口点的顶部?
Api.hs: Api.hs:
{-# LANGUAGE OverloadedStrings #-}
module Api
( whatsTheTime
) where
import Data.Time (getCurrentTime)
import Web.Scotty
import Data.String
whatsTheTime :: IO (ActionM ())
whatsTheTime = do
time <- getCurrentTime
return $ text $ fromString ("The time is now " ++ show time)
Main.hs: Main.hs:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
module Main where
import Api
import Web.Scotty
import Control.Monad.IO.Class
routes = do
get "/" $ do
res <- liftIO whatsTheTime
res
main :: IO ()
main = do
putStrLn "Starting server..."
scotty 3000 routes
(1) This: (1):
do
res <- liftIO whatsTheTime
res
Desugars to this: 糖到此:
liftIO whatsTheTime >>= \ res -> res
If you look at the type of \\ m -> m >>= id
: 如果您查看
\\ m -> m >>= id
:
(Monad m) => m (m a) -> m a
That's exactly the type of join
( Hoogle ), so you can use: 这正是类型
join
( Hoogle ),所以你可以使用:
get "/" $ join $ liftIO whatsTheTime
join
is a common idiom for “execute this action which returns an action, and also execute the returned action”. join
是“执行返回一个动作并执行返回的动作的该动作”的常见用法。
(2) OverloadedStrings
is for overloading of string literals . (2)
OverloadedStrings
用于字符串文字的重载。 You have an overloaded literal "The time is now "
, but you constrain it to be of type String
by using it as an operand of (++)
with a String
(the result of show time
). 你有一个重载的文字
"The time is now "
,但你限制它是类型的String
,把它当做一个操作数(++)
与String
(的结果show time
)。 You can pack the result of show time
as a Text
instead using fromString
or Data.Text.pack
: 您可以使用
fromString
或Data.Text.pack
将show time
的结果打包为Text
:
import Data.Monoid ((<>))
import qualified Data.Text as Text
-- ...
return $ text $ "The time is now " <> Text.pack (show time)
(3) LANGUAGE
pragmas operate per file; (3)
LANGUAGE
Pragma按文件运行; as @mgsloan notes, you can add OverloadedStrings
to the default-extensions:
field of your library or executable in your .cabal
file. 如@mgsloan所述,您可以将
OverloadedStrings
添加到库或.cabal
文件中的可执行文件的default-extensions:
字段中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.