2017-11-16 19 views
2

아래 코드에서 >>을 사용하여 IO 작업을 함께 연결합니다. 그러나 AFAIU, m1>>m2m1>>=(\_.m2)으로 de-sugared되고 바인딩하는 경우 바로 첫 번째 IO 작업을 실행합니다. 모든 인쇄가 주체에서 일어나길 원합니다. 즉, print 문이 입력 문 ("코드 입력")과 인터리브되지 않아야합니다. do 이후로는 [IO()]과 같이 IO보다 다른 모나드를 반환 할 수 없습니다. 원하는 인쇄 효과를 얻으려면 어떻게해야합니까?두 IO() 모나드를 실행하지 않고 어떻게 바인딩 할 수 있습니까?

f :: [Int] -> IO() 
f inventory = do 
     putStrLn "Enter Code\n" 
     x <- getLine 
     let idx = nameToIndex x 
     putStrLn "Quantity\n" 
     y <- getLine 
     putStrLn "More?\n" 
     c <- getChar 
     let q = (read y :: Int) 
     let curM = if inventory !! idx >= q then (putStrLn "sdaf\n") else (putStrLn "Overflow!\n") 
     if c == 'Y' then curM>>(f (update inventory idx)) else curM 

main = f [1, 2] 
+2

아니요'IO'는 IO를 수행하지 않기 때문에 * 처음 상태의 IO를 즉시 실행하지 않습니다. * 기계의 상태를 수정하는 방법을 설명합니다. * 단순히 컴퓨터의 상태를 수정하는 것입니다. 두 개의 'IO'. 사실 하스켈에서는 실제로 필요한 경우를 제외하고는 아무 것도 실행되지 않습니다. –

답변

5

은 내가 문제를 이해하고 100 % 확실하지 않다, 그러나 나는 이렇게되면 생각 : 당신은 다음의 상호 작용에 대한 정보를 저장, 사용자와 어떤 상호 작용을 표시 할 모든 전체 상호 작용의 끝에서 한 번에 정보.

다음은 매우 단순화 된 코드입니다. 모든 비즈니스 로직을 건너 뛰고 계속 진행할 것인지 묻습니다.

prompt = do 
    putStrLn "Continue?" 
    s <- getLine 
    case s of 
     "y" -> putStrLn "Okay, let's continue." >> prompt 
     _ -> return() 

main = prompt 

난 당신이 요구하고있는 효과의 표시 지연하는 것입니다 생각 "좋아, 계속 할 수 있습니다." 사용자가 "y"를 치는 것을 멈출 때까지 그건 아무 문제 없어요. 당신이 이것을 할 수있는 많은 방법이 있습니다. 가장 유연한은이 완료된 후 prompt 복귀가 원하는 작업이 실행되어야하는 것입니다 :

prompt = do 
    putStrLn "Continue?" 
    s <- getLine 
    case s of 
     "y" -> do 
      act <- prompt 
      return (putStrLn "Okay, let's continue." >> act) 
     _ -> return (return()) 

main = do 
    act <- prompt 
    act 

(이이 코드를보다 컴팩트하게 할 수 콤비뿐만 아니라, 수 있습니다.)하지만이 디자인을 좋아하지 않는다 ; 그것은 prompt의 결과에 대해 내성을 갖기 어렵게 만듭니다. 좀 더 전문화되고 유지 보수가 가능한 접근 방식은 상호 작용을 설명하는 데이터를 반환하는 것입니다. 그러면 호출자는 작업을 요약하는 동작으로 바꿀 수 있습니다. 이 경우 문자열 목록이 적합한 설명처럼 보입니다.

prompt = do 
    putStrLn "Continue?" 
    s <- getLine 
    case s of 
     "y" -> do 
      results <- prompt 
      return ("Okay, let's continue." : results) 
     _ -> return [] 

main = do 
    results <- prompt 
    mapM_ putStrLn results 

이 설명을 더 복잡한 비즈니스 논리와 결합 할 수있을만큼 명확합니다.