Haskell: how do you check runtime types on IO?

You did not transform the choice (which is a String) to an RPS, or even better a Maybe RPS:

readRPS :: String -> Maybe RPS
readRPS "rock" = Just Rock
readRPS "paper" = Just Paper
readRPS "scissors" = Just Scissors
readRPS _ = Nothing

Here we thus return a Just x given the input is valid (with x the corresponding RPS item), or Nothing if the string is not a valid option.

We can then implement this as:

import Data.Char(toLower)

main :: IO ()
main = do
    putStrLn "Rock, Paper, or Scissors?"
    choice <- getLine
    case readRPS (map toLower choice) of
        Just rps -> putStrLn (_shoot rps Rock) 
        Nothing -> putStrLn "Invalid choice."
    main

You're nearly there, you just need the read function to convert the user's string to your RPS data type.

The first thing you need to do is to make RPS an instance of the Read typeclass. This can be done easily by amending your data declaration to:

data RPS = Rock | Paper | Scissors deriving Read

what deriving Read does is give RPS a default instance of the Read typeclass, which works in the obvious way: read "Rock" will become Rock and so on, provided the compiler knows you're using read in a context where a value of type RPS is expected.

Then all you need to do, in your main function, is change this:

putStrLn (_shoot choice Rock)

to

putStrLn (_shoot (read choice) Rock)

Since _shoot has a type signature telling GHC that its first argument must be an RPS value, it will know to use the instance of read defined for your RPS type, and all should be well, since you've already restricted the valid user choices to those 3 specific strings.

(Note that for larger programs there are safer and better ways of handling things like this - see Willem's answer for one simple approach - but this is fine for a basic learning exercise.)