discLocation :: Int -> IO Int
discLocation grid = do
putStrLn "Enter number from the grid "
value <- getLine
if read value `elem` [1..50] && validSlot grid (read value)
then return $ read value
else discLocation grid
validSlot :: Int -> Int -> Bool
validSlot _ _ = True
The above will load in ghci and it works as expected. It is important that validSlot knows that its second argument is an Int - so that (read value) can infer that it should return an int. I find the following a bit easier to read
discLocation grid = do
putStrLn "Enter number from the grid "
value <- readLn
if value `elem` [1..50] && validSlot grid value
then return value
else discLocation grid
Here since you are returning value and discLocation is of type Grid -> IO Int, readLn knows that it should read an Int.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…