2014-11-21 2 views

ответ

16

then может принимать только одно значение .... Но вам повезло, потому что do разбивает несколько IO() значения в один ....

if n > 0 
    then do 
    putStrLn "Hello" 
    putStrLn "Anything" 
    else return() 

Помните, что в Haskell вам также нужен elsereturn() создает тривиальный IO(), который ничего не делает).

+9

Если вы не любите 'другое возвращение()' вы можете использовать '' when' из Control.Monad' вместо 'если .., то ... else ... '. – Cirdec

4

Ваш пример не имеет смысла в Haskell. Каждое выражение должно иметь значение, поэтому вам всегда нужно иметь else, даже если это всего лишь return().

Потому что это должно быть одно выражение, вы не можете просто сделать

putStrLn "Hello" 
putStrLn "Anything" 

так как те два выражения типа IO(), что означает, что это computatinon с некоторыми внешними эффектами, и что есть безрезультатно. У вас есть два вычисления, которые должны выполняться в последовательности, которая может быть сделана с помощью >> комбинатор

putStrLn "Hello" >> putStrLn "Anything" 

Существует также альтернативный синтаксис с использованием do блока.

do 
    putStrLn "Hello" 
    putStrLn "Anything" 

Важно отметить, что это будет компилировать в том же >> коде, приведенном выше примере.do блок можно рассматривать только как синтаксический сахар (есть больше к этому, но для простоты вы можете думать об этом таким образом.)

Сведя все это вместе оставляет нас с

if n > 0 
then putStrLn "Hello" >> putStrLn "Anything" 
else return() 

или с помощью сделать блок

if n > 0 
then do 
    putStrLn "Hello" 
    putStrLn "Anything" 
else return() 

Поскольку эта модель является довольно распространенным, существует when комбинатор (в Control.Monad), который делает именно это

when (n > 0) 
    do 
    putStrLn "Hello" 
    putStrLn "Anything" 

или просто

when (n > 0) (putStrLn "Hello" >> putStrLn "Anything") 
Смежные вопросы