2010-07-01 2 views
7

IO를 사용하는 함수를 매핑하는 전통적인 방법이 있습니까? 특히, 난 어떤 종류의 임의의 값을 반환하는 함수를 통해 매핑하고 싶습니다. 노멀 맵을 사용하면 유형 ([IO b])의 결과가 나오지만 IO에서 목록의 값을 푸는 데는 유형 (IO [b])이 필요합니다. 그래서 쓴 ...하스켈의 IO 오버 매핑

mapIO :: (a -> IO b) -> [a] -> [b] -> IO [b] 
mapIO f [] acc = do return acc 
mapIO f (x:xs) acc = do 
    new <- f x 
    mapIO f xs (new:acc) 

... 잘 작동합니다 .... 그러나 하스켈에 내장 된이 솔루션이 있어야하는 것처럼 보입니다. 순서의 관점에서 구현되는

Control.Monad.mapM :: (Monad m) => (a -> m b) -> [a] -> m [b] 

:

getPercent :: Int -> IO Bool 
getPercent x = do 
    y <- getStdRandom (randomR (1,100)) 
    return $ y < x 

mapIO (\f -> getPercent 50) [0..10] [] 
+9

미래에는 [Hoogle] (http://haskell.org/hoogle/?hl=ko (a + - % 3E + IO + b \) + - % 3E + \ [a \] + - % 3E + IO + \ [b \])를 사용하여 겉보기에 명백한 기능이 이미 존재하는지 확인합니다 (일반적으로 수행하기 때문에). 놀랍도록 유용합니다! –

+0

감사합니다. 훌륭한 리소스처럼 보입니다! – unignorant

+1

또한, Hayoo를 확인해보십시오. Hoogle과 비슷하지만 사물을 약간 다르게 검사합니다. – BMeph

답변

21

표준 방법을 통해입니다 : 예를 들어, 예를 들어이 사건을 사용

sequence :: (Monad m) => [m a] -> m [a] 
+0

감사! 정확히 내가 무엇을 찾고 있었는지. – unignorant

+1

그런데'mapM'은 이미 Prelude – newacct

9

그냥 돈의 대답에 추가 할 , 또한 을 수행하지만 모든 결과를 무시하므로 부작용 만있는 mapM_ 기능을 사용하십시오.

이것은 계산이 실행되도록 (예 : IO 계산) 원하는 결과에 관심이없는 경우 (예 : 파일 연결 해제)에 유용합니다.

forMforM_도 참조하십시오.

+7

에 있으며 mapM_은 일정한 스택 공간에서 실행됩니다. 반면 mapM은 sequence_vs sequence와 마찬가지로 선형 스택이 필요합니다. –

+0

@ 시몬, 이것을 언급 해 주셔서 감사합니다. 나는 항상 내지도를보고있다. 목록이 작거나 mapM_을 사용하도록 리팩토링을 시도하기 위해 매우 조심스럽게 생각한다. –