2014-05-20 14 views
3

그래서이 질문은 모나드에 관한 것이고 (구체적으로는 페이), 필자는 IO 모나드를 사용합니다.do not 표기법을 사용하여 목록에 맵을 사용하는 방법 - 즉, 'IO()'유형으로 'IO()'유형을 피 하시겠습니까?

나는 입력이 문자열 목록이고 각 문자열을 하나씩 출력하고 싶습니다. 그래서 내 아이디어는 다음과 같습니다.

funct :: [String] -> ? 
funct strs = do 
    map putStrLn strs 

[IO()] 유형을 반환하기 때문에 작동하지 않습니다. 그래서 내 질문은, 어떻게 목록에 매핑하고, 내가 한 줄씩 함수를 수행하는 것처럼 다루는가, 일반적인 do-notation, 반복 스타일 (아래처럼)?

funct :: [String] -> IO() 
funct strs = do 
    putStrLn (strs !! 0) 
    putStrLn (strs !! 1) 
    ... 
+0

이미 제안 된'Control.Monad '의 표준 함수를 사용하십시오. 또한'funct (h : t) = do {putStrLn h; funct t; }; funct _ = return()' –

답변

12

는 표준 라이브러리 목록 기능의 대부분은 M로 끝나는 모나드 버전이 있습니다. 그들을 찾으려면 hoogle을 사용하는 것이 좋습니다.

특히 귀하의 경우에는 mapM_ putStrLn을 자주 사용합니다.

+0

보너스 포인트를 얻으려면, 'Control.Monad' 문서를 읽고 각 기능을 작성하는 방법을 알아내는 것이 좋습니다. –

5

사용 서열

sequence $ map putStrLn strings 

시퀀스

sequence :: Monad m => [m a] -> m [a] 

따라서 변환 모나드 목록에서 모나드 당긴 (putStrLn 문자열 MAP) :: IO 내지 [IO A]를 [A ]. 관련 sequence_를 사용하여 반환 값을 삭제할 수도 있습니다.

forM_:: Monad m => [a] -> (a -> m b) -> m() (더보기 좋지만 나에게 꼭 필요한 느낌을 주기도합니다)을 사용할 수도 있습니다. 등

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

replicate :: Int -> a -> [a] 
replicateM :: (Monad m) => Int -> m a -> m [a] 

때때로 그들은 때로는 그들이 Control.Monad에, Prelude에 있습니다

+0

'시퀀스. map f는 라이브러리에'mapM f '로 포함되어있다. – kqr