2013-11-22 2 views
1

내가 문제 유형과 기능을 쓰는 데에 배열
Int -> IO [Int] 또는하스켈 IO 및 재귀

Int -> [IO Int] I 작동하지 않는 경우 다음과 같은 코드가 있습니다

createEIList :: Int -> IO [Int] 
createEIList len = do 
    cur <- createEI 
    (return cur):(createEIList (len-1)) 

을 createEI이 createEI :: IO Int

인 경우를

이와 같은 작업을 수행하는 가장 좋은 방법은 무엇입니까?

+0

replicateM :: Monad m => Int -> ma -> m [a], 연구 형 –

답변

5

는 원래

createEIList :: Int -> IO [Int] 
createEIList len = do 
    cur <- createEI 
    rest <- createEIList (len-1) 
    return (cur:rest) 

이 방법을 한 무슨 가까이를 유지하려면, 당신은 당신의 목록에 IO Int를 추가하려고 노력하지만, 오히려 전체 목록 리프팅을 반환하지 않습니다 또한 아마 기본 케이스를하려는 IO [Int]

[Int]

createEIList 0 = return [] 
createEIList n = ... 

그래서 재귀가 실제로 종료됩니다.

또한 가치는 콤비

replicateM :: Int -> IO a -> IO [a] -- Restricted for clarity 

내가 이것을 사용하는 방법을 알아 내기 위해 당신에게 그것을 떠날거야으로 명시 적으로 재귀를 제거 할 수 있음을 지적.

+0

':'는'Int' 타입의 왼쪽 인자와'IO Int'의 오른쪽 인자를 가지지 않을까요? – functorial

+0

@ user2529202 고정, 당신은 모나드 래퍼를 제거하기 위해 이름에 명시 적으로 바인드합니다. – jozefg

+0

'<-'는 IO를 제거한 다음 새로운 요소로 그냥 무시합니다. – jozefg

2

마지막 행은 다음과 createEIList (len-1) >>= \a -> return (cur:a)

+0

나는 람다 대신에'do' 표기법을 고수하는 편이 낫다. 그. –

+0

나는 모든 것을 다시 쓰거나 혼란을 야기 할 위험을 감수하면서 한 줄로 대답 할 수 있기를 원했다. – randomusername

+0

이것은 종료되지 않습니다. –

2
createEIList :: Int -> IO Int  
createEIList len = createEI >>= return . replicate len 

또는

createEIList :: Int -> IO Int 
createEIList len = createEI >>= replicateM len . return 

더 나은 솔루션 :

createEIList :: Int -> IO Int 
createEIList len = replicateM len createEI 

tersest :

createEIList :: Int -> IO Int 
createEIList = flip replicateM createEI 

실용적 :

import Control.Applicative 
createEIList len = replicate <$> pure len <*> createEI 
createEIList' len = liftA2 replicate (pure len) createEI