【问题标题】:calling network IO from within haskeline从 haskeline 中调用网络 IO
【发布时间】:2012-06-13 02:15:25
【问题描述】:

我有一个现有的程序,它接受命令行参数(用户名、密码、日期),然后使用Network.HTTP.Conduit 库将 xml 消息发布到服务器。然后我解析结果,做一些工作并使用 blaze-html 写入文件。

这一切都像一个魅力;但是,我想我会使用 haskeline 以便密码不可见。我可以创建一个命令行程序来获取用户提供的值并将它们打印出来,但是如果我调用使用管道的函数,它永远不会返回。

这是有问题的代码:

main = runInputT defaultSettings loop
where 
    loop :: InputT IO ()
    loop = do
        Just username <- getInputLine "WM username: "
        Just password <- getPassword (Just '*') "WM password: "
        Just date     <- getInputLine "Date (YYYYMMDD): "

        outputStrLn "querying WM..."
        clients <- lift $ getWMClients username password
        outputStrLn "successfully retrieved client list from WM..."

        let outHeader = renderHeader date username

        reportString <- mapM  (\x -> createString x clients)  cList

        lift $ writeFile (date ++ "_report.html") (outHeader ++ concat reportString)
        outputStrLn "Done"

函数getWMClients函数为:

getWMClients :: Username -> String -> IO [Client]
getWMClients username password = do
    let f = [Size "-1", Skip "0"]
    let fs = [Select "id",
              Select "status",
              Select "last-name",
              Select "first-name",
             ]
    let query = WMQuery {transaction=SHARE,service=Query,businessObject=CONT,field=f,fields=fs}

    results <- doQuery username (Just password) Nothing (Just query)
    rows <- xmlResultsToMaps results

    let clients = map makeClient rows
    return clients

当我运行程序时,它会挂在“查询 WM...”处,我认为 http-conduit 从未真正运行过。有关如何进行这项工作的任何提示?

提前致谢, 尼尔

【问题讨论】:

    标签: haskell http-conduit haskeline


    【解决方案1】:

    您声称它在 haskeline 之前使用硬编码的用户名、密码、日期。为了帮助调试,您可能无法将管道提升到 InputT。以下仍然失败吗? (我没有编译这个,所以请随意修复语法错误......)

    -- Isolate the haskeline monad to just the input part:
    main = loop
    where 
        loop :: IO ()
        loop = do
          (username,password,date) <- runInputT defaultSettings $ do
            Just username <- getInputLine "WM username: "
            Just password <- getPassword (Just '*') "WM password: "
            Just date     <- getInputLine "Date (YYYYMMDD): "
            return (username,password,date)
    
          putStrLn "querying WM..."
          clients <- getWMClients username password
          putStrLn "successfully retrieved client list from WM..."
    
          let outHeader = renderHeader date username
    
          putString <- mapM  (\x -> createString x clients)  cList
    
          writeFile (date ++ "_report.html") (outHeader ++ concat reportString)
          putStrLn "Done"
    

    【讨论】:

    • 谢谢 Chris,我认为问题在于 runInpuT 是 () 类型。当我尝试这个时,我收到错误消息:Couldn't match expected type ()' 实际类型为(t0, t1, t2)' In the first argument of return',即(username, password, date)' In the expression: return (username, password, date) In a stmt of a 'do' expression: Just date &lt;- getInputLine "Date (YYYYMMDD): "
    • 我最终分开了循环函数并返回 IO (String, String, String) 并且它起作用了。感谢您的帮助,克里斯。
    猜你喜欢
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多