1

I am having trouble writing a function with type
Int -> IO [Int] or Int -> [IO Int]

I have the following code that is not working:

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

Where createEI is createEI :: IO Int

What is the best way to do something like this?

1
  • replicateM :: Monad m => Int -> m a -> m [a], Study this type Commented Nov 22, 2013 at 3:35

3 Answers 3

5

To keep it close to what you originally had

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

This way, you don't try to append IO Int to your list, but rather return the whole list lifting your [Int] to an IO [Int]

You also probably want a base case

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

So that the recursion actually terminates.

Also worth noting that you can remove the explicit recursion with the combinator

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

I'll leave it to you to figure out how to use this.

Sign up to request clarification or add additional context in comments.

3 Comments

But wouldn't the : have a left argument of type Int and a right argument of IO Int?
@user2529202 Fixed, you pull explicitly bind it to a name to remove it's monadic wrapper
The <- removes the IO and then you can just cons it with the new element
2

The last line should be createEIList (len-1) >>= \a -> return (cur:a)

5 Comments

I think it would be better to stick to the do-notation instead of lambda, since we're already in that.
I wanted to make sure that I could answer in one line rather than having to rewrite the whole thing or risk causing confusion.
This doesn't terminate.
@dave I think it will if you add a case for length being 0 ie. createEIList 0 = return []?
Without lambda - createEIList (len-1) >>= return . (cur :)
2
createEIList :: Int -> IO Int    
createEIList len = createEI >>= return . replicate len

or

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

better solution:

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

tersest:

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

applicative:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.