LiftIO、do 块和语法
LiftIO, do block, and syntax
我正在掌握使用 Scotty 在 Haskell 中编写 API。我的文件在下面提供。我的问题是:
在路由定义中,我在 do 块中从 liftIO whatsTheTime 中提取。这有效,但看起来很冗长。有更好的语法吗?
在 whatsTheTime 定义中,我需要执行 fromString。我原以为 OverloadedString 会解决这个问题,但事实并非如此。如果有人指出为什么没有 fromString 就无法工作,我将不胜感激。
在堆栈项目中,如果我需要像 OverloadedStrings 这样的指令,我是否需要将它包含在每个需要它的文件中,还是仅包含在主入口点的顶部?
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:
{-# 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) 这个:
do
res <- liftIO whatsTheTime
res
脱糖:
liftIO whatsTheTime >>= \ res -> res
如果你看\ m -> m >>= id
的类型:
(Monad m) => m (m a) -> m a
这正是join
(Hoogle)的类型,所以你可以使用:
get "/" $ join $ liftIO whatsTheTime
join
是“执行这个returns一个动作的动作,并且还执行返回的动作”的常用成语。
(2) OverloadedStrings
用于重载字符串 文字 。您有一个重载文字 "The time is now "
,但您通过将其用作 (++)
的操作数和 String
([=23 的结果)来将其限制为 String
类型=]).您可以将 show time
的结果打包为 Text
而不是使用 fromString
或 Data.Text.pack
:
import Data.Monoid ((<>))
import qualified Data.Text as Text
-- ...
return $ text $ "The time is now " <> Text.pack (show time)
(3) LANGUAGE
pragmas 按文件操作;正如@mgsloan 指出的那样,您可以将 OverloadedStrings
添加到 .cabal
文件中库或可执行文件的 default-extensions:
字段。
我正在掌握使用 Scotty 在 Haskell 中编写 API。我的文件在下面提供。我的问题是:
在路由定义中,我在 do 块中从 liftIO whatsTheTime 中提取。这有效,但看起来很冗长。有更好的语法吗?
在 whatsTheTime 定义中,我需要执行 fromString。我原以为 OverloadedString 会解决这个问题,但事实并非如此。如果有人指出为什么没有 fromString 就无法工作,我将不胜感激。
在堆栈项目中,如果我需要像 OverloadedStrings 这样的指令,我是否需要将它包含在每个需要它的文件中,还是仅包含在主入口点的顶部?
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:
{-# 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) 这个:
do
res <- liftIO whatsTheTime
res
脱糖:
liftIO whatsTheTime >>= \ res -> res
如果你看\ m -> m >>= id
的类型:
(Monad m) => m (m a) -> m a
这正是join
(Hoogle)的类型,所以你可以使用:
get "/" $ join $ liftIO whatsTheTime
join
是“执行这个returns一个动作的动作,并且还执行返回的动作”的常用成语。
(2) OverloadedStrings
用于重载字符串 文字 。您有一个重载文字 "The time is now "
,但您通过将其用作 (++)
的操作数和 String
([=23 的结果)来将其限制为 String
类型=]).您可以将 show time
的结果打包为 Text
而不是使用 fromString
或 Data.Text.pack
:
import Data.Monoid ((<>))
import qualified Data.Text as Text
-- ...
return $ text $ "The time is now " <> Text.pack (show time)
(3) LANGUAGE
pragmas 按文件操作;正如@mgsloan 指出的那样,您可以将 OverloadedStrings
添加到 .cabal
文件中库或可执行文件的 default-extensions:
字段。