0

我试图创建自己的字符串洗牌功能:

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

它返回错误消息:

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)) }

我看到它与 IO 有关,但我不知道如何解决它。

4

1 回答 1

4

首先,您没有将字符串参数传递给remove_charand get_char。此外,您需要将结果get_char转换为列表才能使用++. 递归调用my_shuffle应如下所示:

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

其次,您需要使用 IO monad for randomIO,因此 的签名my_shuffle应该是:

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

然后最后你需要return在基本情况下使用(因为你需要返回一个IO [Char]):

my_shuffle [] result = return result

应用了修复:

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
于 2012-10-29T14:25:47.123 回答