2013-02-19 3 views
2

이 내가 가지고있는, 내가 원하는 써머없이 내가 그러나 점점 계속이하스켈 잘못된 IO 출력

*Main> sumThree 
Please enter three integers: 
1 
2 
3 
Their sum is: 6 
(1,2,3) 

같은 출력, 당신이이

*Main> sumThree 
Please enter three integers: 
1 
2 
3 
Their sum is: 
(1,2,3) 

**summ :: Integer -> Integer -> Integer -> IO Integer 
summ x1 x2 x3 = return(x1+x2+x3) 
sumThree :: IO (Integer, Integer, Integer) 
sumThree = do putStr "Please enter tree integers:" 
       x1 <- getInteger 
       x2 <- getInteger 
       x3 <- getInteger 
       putStr "Their Sum is: " 
       summ x1 x2 x3 
       return(x1,x2,x3)** 

답변

2

실제로 summ의 결과를 인쇄하십시오.

summ 함수에 return이 없으므로 함수의 결과 유형은 IO Integer이 아닌 Integer이됩니다. 그런 다음 summ x1 x2 x3 대신

putStr (show (summ x1 x2 x3)) 

대신에 수행하십시오.

또한 sum 내장 (Prelude) 기능에 대해 알고 계십니까? Num의 배열을 사용하기 때문에 putStr (show (sum [x1, x2, x3]))을 사용할 수 있습니다.

+0

당신이 기능 만 1 수익을 가질 수 있습니다 sumThree을 인쇄뿐만 아니라 값을 생성해야하는 경우, 이와 비슷한 더 많은 것을 원하는 것? –

+1

아니요 하나 이상의 반품을 할 수 없습니다. 하스켈에서'return'은 일부 모나드 M에 대해 'a -> M a'라는 서명을 가진 함수입니다.이 경우에, 당신은'IO' 모나드에 있기 때문에 'return'은'a - > IO a'. 모나드 (Monads)와 하스켈 (Haskell)에서 어떻게 작동하는지 읽어야합니다. 즉, 하스켈에서 (그리고 모나드 용어로)'리턴 '은 평범한 가치를 모나드 값으로 변환하는 함수 일 뿐이며 명령형 언어의 "return statement"개념과는 전적으로 관련이 없다. – tom

+0

예 http://codepad.org/GIuCUlBc –

1

여기에 코드를 너무 많이 읽었을 수 있습니다. 잘못된 것이라면 저를 고쳐주십시오. 그러나 하스켈 프로그램의 작동 방식에 대해 혼란스러워하고 특히 return의 의미에 대해 혼란스러워합니다.

return의 하스켈은 많은 명령형 프로그래밍 언어에서 익숙한 return 문이 아닙니다. 하스켈에서 return이고 기능은입니다. 다른 함수와 마찬가지로 값을 계산하기 위해 인수에 적용합니다. 그것은 흐름 제어에 영향이 없으며, 특히 그것의 인수 당신이있어 함수에 의해 계산 된 값으로 "반환"할 수 있습니다. IO 모나드를 들어

, return이의 함수 발생하지 않습니다 이 유형은 return :: a -> IO a입니다. 즉, 모든 유형의 값을 가져 와서 해당 유형의 IO 버전에서 값을 제공합니다. return의 특별한 경우에는, 그 값을 생성 할 아무 것도하지 않는 IO 계산을 제공합니다.

:

summ :: Integer -> Integer -> Integer -> IO Integer 
summ x1 x2 x3 = return(x1+x2+x3) 

은 하스켈 프로그래머 매우 홀수 함수이다. 3 정수의 합계를 계산하기 위해 IO를 수행 할 필요가 없으므로 결과 유형은 왜 IO Integer입니까? 그것은 은 당신이 작성하는 노력했습니다처럼 나에게 보이는 : Integer는 모나드 타입되지 않는 대해 당신에게 유형의 오류를 준 것

summ :: Integer -> Integer -> Integer -> Integer 
summ x1 x2 x3 = return(x1+x2+x3) 

. 유형을 변경하여 문제를 해결할 수 있지만 유형은 3 정수를 합산하는 올바른 표현 이었으므로이를 다른 것으로 변경하는 것은 다소 이상합니다. return 컴퓨터에 함수의 결과가 전혀 필요 없기 때문에, 당신은 대신이 작업을 수행 할 수 있습니다

summ :: Integer -> Integer -> Integer -> Integer 
summ x1 x2 x3 = x1+x2+x3 

가 마찬가지로, 당신의 sumThree 기능이 매우 이상하다.당신은 하스켈 인터프리터에서이 작업을 수행 할 때 :, 값 (1, 2, 3)을 생성합니다

*Main> sumThree 
Please enter three integers: 
1 
2 
3 
Their sum is: 
(1,2,3) 

을 인터프리터는 3 개 정수와 지문을 입력 묻는 sumThree IO 활동을 평가하고있다 "그들의 합계입니다." sumThree 작업 자체는 "Their sum is:" 이후에 아무 것도 인쇄하지 않습니다. 이는 사용자를 위해 인쇄하는 인터프리터이며, sumThree을 실행하여 생성 된 값을 인쇄합니다.

do 블록에서 마지막 값은 sumThree에 의해 생성 된 값을 결정합니다. 이 경우는 return(x1,x2,x3)입니다. 따라서 세 개의 숫자의 합이 될 수있는 방법이 없다는 것을 알 수 있습니다. 튜플을 (x1, x2, x3)으로 명시 적으로 가져와 IO 동작으로 마무리하고 return을 입력하면 그 결과입니다.

두 번째 마지막 줄 :

summ x1 x2 x3 

IO 행동 (유형 summ에 대한 Integer -> Integer -> Integer -> IO Integer 덕분에)입니다. 그래서 그곳에 앉아있을 수 있으며, 그 가치를 생산하기 위해 "실행"됩니다. 그러나 당신은 그걸로 아무 것도하지 않습니다!

그래서 두 가지 :

  1. summ에서 return을 필요로하지 않는 모든
  2. sumThree 실제로 당신이 그 함께이 뭔가를 얻을 수 퍼팅

를 인쇄하려면 무엇을 인쇄해야합니다 :

summ :: Integer -> Integer -> Integer -> Integer 
summ x1 x2 x3 = x1 + x2 + x3 

sumThree :: IO() 
sumThree = do putStr "Please enter tree integers:" 
       x1 <- getInteger 
       x2 <- getInteger 
       x3 <- getInteger 
       putStr "Their Sum is: " 
       putStr (show (summ x1 x2 x3)) 

sumThree이 합계를 산출하고 인쇄하는 것을 원하지 않는 경우입니다.

summ :: Integer -> Integer -> Integer -> Integer 
summ x1 x2 x3 = x1 + x2 + x3 

sumThree :: IO Integer 
sumThree = do putStr "Please enter tree integers:" 
       x1 <- getInteger 
       x2 <- getInteger 
       x3 <- getInteger 
       putStr "Their Sum is: " 
       putStr (show (summ x1 x2 x3)) 
       return (summ x1 x2 x3)