2012-06-13 2 views
5

У меня есть существующая программа, которая принимает аргументы командной строки (имя пользователя, пароль, дата), а затем использует библиотеку Network.HTTP.Conduit для размещения XML-сообщения на сервере. Затем я разбираю результаты, делаю некоторые работы и использую blaze-html для записи в файл.вызов сети IO изнутри haskeline

Все работает как шарм; однако я думал, что буду использовать 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 на самом деле работает. Любые подсказки о том, как сделать эту работу?

Спасибо заранее, Нил

ответ

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" 
+0

Спасибо Крис, я думаю, проблема в том, что 'runInpuT' имеет тип(). Когда я пытаюсь это сделать, я получаю сообщение об ошибке: 'Не удалось сопоставить ожидаемый тип'() 'с фактическим типом '(t0, t1, t2)' В первом аргументе' return ', а именно '(имя пользователя, пароль, дата) ' В выражении: return (имя пользователя, пароль, дата) В выражении выражения' do ': Только дата <- getInputLine "Дата (YYYYMMDD):" ' – Neil

+0

Я закончил функция цикла отдельно и возвращает IO (String, String, String), и это сработало. Спасибо за помощь Крис. – Neil

Смежные вопросы