ceth
ceth

Reputation: 45325

Type error in string shuffle function

I have tried to create my own string shuffle function:

import System.Random

-- usage case: my_shuffle "something" ""

my_shuffle :: [Char] -> [Char] -> [Char]
my_shuffle [] result = result
my_shuffle s result = do 
    pos <- randomRIO (1, length s)
    my_shuffle (remove_char pos) (result ++ (get_char pos))

get_char :: [Char] -> Int -> Char
get_char s pos  = s !! (pos - 1)

remove_char :: [Char] -> Int -> [Char]
remove_char s pos = take (pos - 1) s ++ drop pos s

It returns the error message:

substitution_cipher.hs:8:16:
    Couldn't match expected type `[t0]' with actual type `IO a0'
    In the return type of a call of `randomRIO'
    In a stmt of a 'do' expression: pos <- randomRIO (1, length s)
    In the expression:
      do { pos <- randomRIO (1, length s);
           my_shuffle (remove_char pos) (result ++ (get_char pos)) }

As I see it is related to IO, but I don't know how to fix it.

Upvotes: 0

Views: 157

Answers (1)

ErikR
ErikR

Reputation: 52049

First of all, you aren't passing the string argument toremove_char and get_char. Also, you need to turn the result of get_char into a list in order to use ++. The recursive call to my_shuffle should look like:

my_shuffle (remove_char s pos) (result ++ [get_char s pos])

Secondly, you need to use the IO monad for randomIO, so the signature of my_shuffle should be:

my_shuffle :: [Char] -> [Char] -> IO [Char]

Then finally you need to use return in the base case (since you need to return an IO [Char]):

my_shuffle [] result = return result

With fixes applied:

import System.Random

my_shuffle :: [Char] -> [Char] -> IO [Char]
my_shuffle [] result = return result
my_shuffle s result = do
     pos <- randomRIO (1, length s)
     my_shuffle (remove_char s pos) (result ++ [get_char s pos])

get_char :: [Char] -> Int -> Char
get_char s pos  = s !! (pos - 1)

remove_char :: [Char] -> Int -> [Char]
remove_char s pos = take (pos - 1) s ++ drop pos s

Upvotes: 4

Related Questions