gpt4 book ai didi

haskell - 如何在 Scotty Action 中使用 System.command

转载 作者:行者123 更新时间:2023-12-05 00:10:04 26 4
gpt4 key购买 nike

我正在尝试学习 Haskell 中的语句是如何工作的。我试图制作一个非常简单的程序,您可以在其中调用 REST 端点并执行系统命令(非常简单,例如“ls”) 问题在于在单个 do 语句中组合不同的操作类型。


import Web.Scotty
import System.Cmd

main = do
putStrLn "Starting Server"
scotty 3000 $ do
get "/url" $ do
system "ls"
text "Success"

但我收到下一个编译器错误:
Main.hs:12:7:
Couldn't match expected type ‘Web.Scotty.Internal.Types.ActionT
Data.Text.Internal.Lazy.Text IO a0’
with actual type ‘IO GHC.IO.Exception.ExitCode’
In a stmt of a 'do' block: system "ls"
In the second argument of ‘($)’, namely
‘do { system "ls";
text "Success" }’


我很难学习 Haskell!

最佳答案

在 Haskell 中, do -notation用于链接类似语句的东西。语句是某种类型的构造函数,如 IO应用于特定的结果类型。例如,语句 system "ls"有类型 IO ExitCode .

IO 之外的其他类型构造函数可以作为语句使用。所有这些 do -notation 要求类型构造函数实现 Monad interface这解释了如何明智地链接语句。

然而,内单do -block,只允许一种类型的语句!他们必须都是 IO声明,或所有 ActionT Text IO声明。在您的示例中,您将两者混合在一起,这会导致错误。 Scotty's get 函数需要一个 ActionT Text IO 陈述:

get :: RoutePattern -> ActionM () -> ScottyM ()
-- ActionM is actually a synonym for ActionT Text IO

好消息是有一种方法可以转换(通常的 Haskell 术语是“提升”) IO声明成 ActionT Text IO声明。后者实际上是 IO 之上的一种“装饰器”(通常的 Haskell 术语是 "monad transformer" )操作,启用与 Scotty 相关的额外功能。您可以“举” IO使用 liftIO 进入装饰器的操作函数,像这样:
get "/url" $ do                         
liftIO (system "ls")
text "Success"

一般什么时候可以用 liftIO举起平原 IO语句变成“装饰”语句? “装饰器”类型构造函数必须有 MonadIO 除了通常的实例 Monad实例。 MonadIO是什么提供了 liftIO功能。

在我们的例子中,查看 ActionT 的可用实例:
(MonadIO m, ScottyError e) => MonadIO (ActionT e m)

这意味着类似“如果 m 有一个 MonadIO 实例——就像 IO 一样——而错误类型 e 有一个 ScottyError 实例——就像 Text 那样——然后我们可以提升 |1046 | 声明到 IO 声明”。

以及 ActionT e m 的专用类型是:
liftIO :: IO a -> ActionT Text IO a

关于haskell - 如何在 Scotty Action 中使用 System.command,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58670103/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com