LiftIO,阻止和语法

时间:2017-11-02 07:59:30

标签: haskell haskell-stack

我正在努力使用Scotty在Haskell中编写API。我的文件如下。我的问题是:

  1. 在路线定义中,我从一个块中提取了liftIO whatsTheTime。这有效,但似乎很冗长。有更好的语法吗?

  2. 在whatsTheTime定义中,我需要做fromString。我以为OverloadedString会考虑到这一点,但事实并非如此。如果有人指出为什么没有fromString就无法工作,我真的很感激。

  3. 在堆栈项目中,如果我需要像OverloadedStrings这样的指令,我是否需要将它包含在需要它的每个文件中,或者只是在主入口点的顶部?

  4. 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 个答案:

答案 0 :(得分:3)

(1)这:

do
  res <- liftIO whatsTheTime
  res

Desugars to this:

liftIO whatsTheTime >>= \ res -> res

如果你看一下\ m -> m >>= id的类型:

(Monad m) => m (m a) -> m a

这正是joinHoogle)的类型,因此您可以使用:

get "/" $ join $ liftIO whatsTheTime

join是“执行此操作的常用习惯用法,它返回一个操作,并执行返回的操作”。

(2)OverloadedStrings用于重载字符串文字。您有一个重载的文字"The time is now ",但是您将其作为String的操作数(++)({{1}的结果)将其约束为String类型}})。您可以使用show timeshow timeText的结果打包为fromString

Data.Text.pack

(3)import Data.Monoid ((<>)) import qualified Data.Text as Text -- ... return $ text $ "The time is now " <> Text.pack (show time) pragma对每个文件进行操作;正如@mgsloan所说,您可以将LANGUAGE添加到您的资源库的OverloadedStrings字段或default-extensions:文件中的可执行文件。