2014-07-27 1 views
0

여기에 if 문에서 사용하려는 작은 코드 블록이 있습니다. 코드 내 이해에서 더 아래 다음람다 내부에서 IO Int를 비교하는 중 오류가 발생했습니다.

getRandomInt :: (Int, Int) -> IO Int 
getRandomInt (a, b) = do 
    g <- newStdGen 
    return . fst $ randomR (a, b) g 

...

if ((getRandomInt (0,1)) >>= (\x -> x == 1)) 

이며,이 randomInt == 1 아래로 컴파일하고 내부 if 문으로 사용할 수 있어야합니다. 대신에; 나는이 오류를 얻을 : 어떤 뻔뻔스러운 오해에 대한

word.hs:30:21: 
    Couldn't match expected type `Bool' with actual type `IO b0' 
    In the expression: ((getRandomInt (0, 1)) >>= (\ x -> x == 1)) 
    In a stmt of a 'do' block: 
     if ((getRandomInt (0, 1)) >>= (\ x -> x == 1)) then 
      getRandomVowel : (getWord $ len - 1) 
     else 
      getRandomConsonant : (getWord $ len - 1) 
    In the expression: 
     do { if ((getRandomInt (0, 1)) >>= (\ x -> x == 1)) then 
       getRandomVowel : (getWord $ len - 1) 
      else 
       getRandomConsonant : (getWord $ len - 1) } 

미안, 난 그냥 어제 하스켈을 배우기 시작했다.

답변

5

(>>=)의 유형은 Monad m => m a -> (a -> m b) -> m b입니다. 이 경우 m = IO입니다.

그래서 당신은 두 가지 문제가 있습니다

첫째, \x -> x == 1Bool 아닌 IO Bool을 반환을, 그래서 (>>=)에 두 번째 인수로 적합하지 않습니다.

\x -> return (x == 1)으로 변경하면 쉽게 해결할 수 있지만 매우 깨끗한 해결책은 아니며 결과가 Bool이 아닌 IO Bool 인 것으로 나타납니다.

유형 오류로 인해 ifBool 인수를 예상하지만 IO something이 표시됩니다. >>=이 (여기 IO에 전문) 유형이 있기 때문에,

x <- getRandomInt (0,1) 
if x == 1 then ... 
+0

나는 당신이 제안한 것을 시도했다. 그러나 이것은 내가 처음 게시물에 편집 한 다소 더 비밀스러운 오류만을 주었다. – Aearnus

+1

그것은'getWord'에서 다른 문제입니다. '[IO Char] '대신에 타입을'IO [Char]'로 변경해보십시오 - 그것들은 매우 다른 두 가지입니다. 'if'의 각 브랜치와'otherwise'의 경우에는 몸에'return's이 필요할 것입니다. –

+0

오, 나는 나머지 기능에서 내가 잘못한 것을 본다.나머지 부분을 고치면이 오류에 대해 더 자세히 살펴볼 것입니다. 이 오류는이 기능이 고장 나서 발생하지 않는 한. – Aearnus

0

((getRandomInt (0,1)) >>= (\x -> x == 1))이 작동하지 않습니다 :

깨끗한 솔루션은 별도의 <- 라인에 getRandomInt 전화를 꺼냅니다하는 것입니다 IO a -> (a -> IO b) -> IO b,하지만 (\x -> x==1)있다 형식 (Int 여기에 특화) : Int -> Bool, 그래서 귀하의 유형이 일치하지 않습니다. 문제는 아주 쉽게 해결할 수 있습니다. 실제로 여기에 순수한 함수를 적용하는 함수가 있습니다 : liftM :: Monad m => (a->b) -> m a -> m b (이 사실을 알고 있다면 fmap과 거의 같습니다).

두 번째 문제는 if 문에 Bool 대신 IO Bool을 사용할 수 없다는 것입니다 (오류가 무엇을 말하고 있는지, 유형 검사기가 실제로 얻지 못했음). 그 타입이 아마 옳을 수 없다는 것을 알아 내기 훨씬 전에).

내 개인적인 제안은 가능하다면 IO을 현재 사용하지 않는 것이 좋습니다. 그것은 명령형 언어에서 익숙해 진 것과 똑같은 방식으로 작동하지 않으며, 하스켈을 완전히 이해하기 위해서는 약간 더 나은 이해가 필요합니다.

관련 문제