2013-03-24 4 views
3

Я пишу небольшую утилиту командной строки в Haskell, которая должна принимать команду с необязательным аргументом командной строки, но если аргумент отсутствует, пользователю должно быть предложено ввести его *. Например:Выполнение readLine внутри a, если

$ my_prog add item_name 
Adding... done 

$ my_prog add 
Enter item name: item_name 
Adding... done 

Моя первая попытка выглядела примерно так:

add args = do 
    let id = if length args > 0 
     then head args 
     else input where 
      input <- readLine 
    -- Do stuff with id 
    putStrLn id 

, который не смог разобрать на <-.

* С тех пор я решил, что это глупая идея, но я думал, что все равно задам вопрос.

+1

Кроме того, как правило, лучше использовать 'not (null args)', чем 'length args> 0'. На самом деле, поскольку вы используете 'head' позже, вероятно, лучше всего просто сопоставить шаблон с аргументами case из [] -> readLine; x: _ -> return x' –

+0

@BenMillwood Совпадение шаблона имеет смысл, но что такое сделка с 'not (null args)'? Требуется ли Haskell 'O (n)' время для получения длины? –

+1

Точно. Рассмотрим, в частности, случай бесконечного списка! (здесь довольно безопасно предположить, что 'args' не бесконечен, но часто бывает, что если ваш алгоритм терпит неудачу в бесконечном случае, то он плохо работает в большом случае) –

ответ

8

Вы пытаетесь использовать do -notation внутри if, это не будет работать (и, кроме того, не будет typecheck поскольку вся if находится вне IO монады).

add args = do 
    id <- if length args > 0 
       then return $ head args 
       else readLine 
    putStrLn id 
+0

Спасибо, это делает полный смысл сейчас - по какой-то причине Я не сделал прыжок, чтобы положить '<-' вне' if'! –

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