Haskell IO Int and Int

I recently started to learn Haskell. I am trying to write a program that selects a random array element:

import System.Random

randomInt :: (Int, Int) -> IO Int
randomInt range = randomRIO range :: IO Int

choseRandom :: [a] -> a
choseRandom list = 
    length list
    >>=
        (\l -> randomInt(0,l-1))
        >>=
            (\num -> (list !! num))

main :: IO ()
main = undefined

and I get the following error:

Build FAILED

C:\Users\User\Haskell\Real\src\Main.hs: line 7, column 9:
  Couldn't match expected type `IO Int' with actual type `Int'

    In the return type of a call of `length'

    In the first argument of `(>>=)', namely `length list'

    In the first argument of `(>>=)', namely

      `length list >>= (\ l -> randomInt (0, l - 1))'

what am I doing wrong? It's hard for me to deal with monads for the first time

+4
source share
4 answers

Since you are using IO internally choseRandom, you need to change the type signature:

choseRandom :: [a] -> IO a

secondly, you do not need to use >>=to get the length of the list. >>=has type

Monad m => m a -> (a -> m b) -> m b

The type lengthis equal [a] -> Int, so the type length listis equal Int, which is not a monad.

You can calculate it directly by calling randomInt:

choseRandom :: [a] -> IO a
choseRandom list = 
    randomInt(0, length list) >>= (\num -> return (list !! num))

which coincides with

choseRandom :: [a] -> IO a
choseRandom list = fmap (\num -> (list !! num)) (randomInt(0, length list))
+7

, , . :

choseRandom list = do
   let l = length list
   num <- randomInt(0,l-1)
   return (list !! num)

?

: randomRIO, , (, ). , randomRIO IO Monad.

main , "" .

+7

:

import System.Random

randomInt :: (Int, Int) -> IO Int
randomInt range = randomRIO range :: IO Int

choseRandom :: [b] -> IO b
choseRandom list = randomInt (0, length list) >>= \x -> return $ list !! x

:

choseRandom list = do
 a <- randomInt (0, length list)
 return $ list !! a

selectRandom , . >>= m a -> (a -> m b) -> m b, , return.

:

randomInt (0, length list)will give you IO Intand using the function >>=you extract from it Int. Now you can extract the corresponding item from the list using the function !!. But since there should be a type of output m b, you will reset it back to the monad using return.

+4
source

First, you need to fix the fo type signature choseRandom. Secondly, I think you will find it much easier if you use notation do.

choseRandom :: [a] -> IO a
choseRandom list = do
  let l = length list
  num <- randomInt (0, l-1)
  return (list !! num)
+3
source

Source: https://habr.com/ru/post/1537069/


All Articles