No instance for (MonadIO []) arising from a use of ‘liftIO’

Viewed 229

I have this function:

canMoveTo2 :: (Int,Int) -> [(Int,Int)]
canMoveTo2 pos = do
    contents <- liftIO $ readFile "path_to_my_file"
    let currentPositions = [(digitToInt $ contents !! 0,digitToInt $ contents !! 1)]
    currentPositions

What I'm trying to do is read a file, storage its contents as a string, mount a [(Int,Int)] named currentPositions and return it.

The error I'm getting is:

No instance for (MonadIO []) arising from a use of ‘liftIO’

I'm learning haskell for about 1 month now, it seems like the problem is with some instance, but I really don't get what instance means. Can anyone help me understand this error and find a solution? I've come from a JS and PHP background.

1 Answers

You cannot work with liftIO if the monadic context is a list. A list is not an "enriched" IO, like for example MaybeT IO is. It is thus not possible to use readFile to read a file if the output type of canMove2 is a list.

You can make an IO monad that will produce a list with:

canMoveTo2 :: (Int,Int) -> IO [(Int,Int)]
canMoveTo2 pos = do
    c0 : c1 : _ <- readFile "path_to_my_file"
    pure [(digitToInt c0, digitToInt c1)]

You can perform this for example once in the main, and then pass the listof currentPositions as parameter to another function.

Related