2012-05-13 3 views
2

Прошу прощения, что я нехорошо говорить по-английски.оценить «main = return (getChar, getChar)»

Посмотрим код ниже.

main = getChar 

первого, основной будет оцениваться, и это значение «GetChar», но компилятор не знает значение «GetChar», поэтому компилятор будет оценивать «GetChar» вычислить значение «GetChar», и так, getChar будет выполнен.

Фактически, когда я проверил код выше. .. «GetChar выполняется

Давайте посмотрим код ниже

main = return (getChar, getChar) 

Во-первых, основной оценке, это значение возврата (не определено, не определено) -> IO (не определено, не определено), поэтому прелюдия будет оценивать IO (undefined, undefined), чтобы напечатать значение, поэтому будет оценен один из двух getChar.

но, когда я проверил код выше, ни один из двух getChar не был оценен. Я не понимаю, почему ни один из двух getChar не является оценивается.

+1

Кстати, где вы получили информацию о том, что результат main должен быть напечатан? Это не так. Так или иначе, он все равно отбрасывается. – Ingo

+2

'return X' не выполняет эффекты' X'. Например, 'main = return getChar' ничего не сделает. – sdcvvc

+0

Может ли кто-нибудь здесь предоставить версию этого кода в аппликативном стиле, что делает то, что хочет OP? – hugomg

ответ

4

Вы должны фактически выполнить свой монадический акт ионы затем возвращают результаты их выполнения.

func = do 
    a <- getChar 
    b <- getChar 
    return (a,b) 

То, что вы сейчас делаете, как заявление C:

void main(char &a, char &b) 
{ 
    a = getchar; 
    b = getchar; 
} 

в отличие от того, что вы действительно хотите:

void main(char &a, char &b) 
{ 
    a = getchar(); 
    b = getchar(); 
} 
+0

Спасибо, Томас. Я знаю, что я должен использовать «делать нотацию» для последовательного выполнения монадического значения. – user1286894

+0

В этом случае я не понимаю, в чем проблема. Если бы вы могли предоставить подпись или поведение типа, которые вы хотите, и то, что вы наблюдаете, то это поможет. –

+0

Я хочу знать, почему ни один из двух getChar не оценивается. – user1286894

0

«Я хочу, чтобы знать, почему ни один из два getChar не оцениваются "

Во-первых, на английском языке, как и в логике или математике или Haskell (не (не р)) == р, следовательно, ваш вопрос:

Я хочу знать, почему оба из двух GetChars оцениваются.

Смущает, потому что я уверен, ни одно из них не оценивается.

Ваша основная функция вычисляет значение IO a, а затем вычисляется значение внутри IO с типом a. В вашем случае a (IO Char, IO Char). Поскольку Haskell является нестрогим языком, оценка кортежа просто означает построение кортежа. Это не включает оценку компонентов кортежа. Например:

fst (42, 7 `quot` 0 :: Int) 

не прерывается с делением на нулевую ошибку. Следовательно, мы имеем:

(getChar, getChar) 

является кортежем с 2 невычисленными значениями. Но даже если значения оцениваются, мы имеем 2 значения типа IO Char. Такое значение можно рассматривать как действие, которое, когда выполняется в монаде IO, возвращает Char.

Следовательно, не только ваши компоненты кортежа не оцениваются, они также не выполняются в IO-монаде.

Для достижения этой цели можно передать кортеж с двумя действиями на другое действие:

executeBoth (a,b) = do 
    ra <- a 
    rb <- b 
    return (ra, rb) 

Теперь иди, проверьте тип executeBoth и вы, вероятно, увидеть точку.

+0

спасибо тонну. Извините за мою ошибку. Я изменил это. Это означает, что «ни один из них не оценивается». – user1286894

+0

читает ваши ответы, поэтому теперь я знаю, что «main = (undefined, undefined)» не будет оцениваться. – user1286894

+0

но, у меня вопрос. Когда haskell компилирует «main = getChar», я думаю, что haskell оценивает его на «main = undefined», поэтому «getChar» не будет оцениваться. но когда я тестирую код, он был оценен. можете ли вы это объяснить? – user1286894