Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 字符串洗牌函数中的类型错误_Haskell_Types - Fatal编程技术网

Haskell 字符串洗牌函数中的类型错误

Haskell 字符串洗牌函数中的类型错误,haskell,types,Haskell,Types,我已尝试创建自己的字符串洗牌函数: 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

我已尝试创建自己的字符串洗牌函数:

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
导入系统。随机
--用例:my_shuffle“something”“”
我的洗牌::[Char]->[Char]->[Char]
我的洗牌[]结果=结果
my_shuffle s result=do
pos Int->Char
获取\u char s pos=s!!(位置-1)
删除字符::[char]->Int->[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)) }
substitution\u cipher.hs:8:16:
无法将预期类型“[t0]”与实际类型“IO a0”匹配
在“randomRIO”调用的返回类型中

在'do'表达式的stmt:pos首先,您没有将字符串参数传递给
remove\u char
get\u char
。此外,您需要将
get_char
的结果转换为一个列表,以便使用
++
。对
my_shuffle
的递归调用应该如下所示:

my_shuffle (remove_char s pos) (result ++ [get_char s pos])
其次,您需要为
randomIO
使用IO monad,因此
my\u shuffle
的签名应该是:

my_shuffle :: [Char] -> [Char] -> IO [Char]
最后,您需要在基本情况下使用
return
(因为您需要返回
IO[Char]
):

应用修复后:

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
导入系统。随机
my_shuffle::[Char]->[Char]->IO[Char]
my_shuffle[]result=返回结果
my_shuffle s result=do
pos Int->Char
获取\u char s pos=s!!(位置-1)
删除字符::[char]->Int->[char]
删除字符s pos=take(pos-1)s++drop pos s

首先,您没有将字符串参数传递给
remove\u char
get\u char
。此外,您需要将
get_char
的结果转换为一个列表,以便使用
++
。对
my_shuffle
的递归调用应该如下所示:

my_shuffle (remove_char s pos) (result ++ [get_char s pos])
其次,您需要为
randomIO
使用IO monad,因此
my\u shuffle
的签名应该是:

my_shuffle :: [Char] -> [Char] -> IO [Char]
最后,您需要在基本情况下使用
return
(因为您需要返回
IO[Char]
):

应用修复后:

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
导入系统。随机
my_shuffle::[Char]->[Char]->IO[Char]
my_shuffle[]result=返回结果
my_shuffle s result=do
pos Int->Char
获取\u char s pos=s!!(位置-1)
删除字符::[char]->Int->[char]
删除字符s pos=take(pos-1)s++drop pos s

如果您不确定类型,通常可以省略类型签名,将其加载到GHCi中,然后执行
:t
,让Haskell告诉您类型。然后,您可以将该类型签名添加到源中。如果您不确定某个类型,通常可以省略该类型签名,将其加载到GHCi中,然后执行
:t
以使Haskell告诉您该类型。然后您可以将该类型签名添加到源代码中。非常感谢您的详细回答。但我还有一个问题:有没有办法从我的_shuffle返回[Char],而不是IO[Char]。我想将结果用作公共字符串:fab=a++b;f“some”(my_shuffle“some”“)@demas:No。纯函数必须为相同的输入返回相同的结果,而
my_shuffle
显然不返回相同的结果,因此它必须位于
IO
中,以表明它是不确定的。要将它与
f
一起使用,例如,您可以编写
f“some”my\u shuffle“some”
,它将再次出现在
IO
中。另一个选择是通过将随机数生成器作为输入使其具有确定性,但您必须担心传递。@demas-您使用的是
randomRIO
,这意味着您必须返回一个
IO[Char]
。非常感谢您提供的详细答案。但我还有一个问题:有没有办法从我的_shuffle返回[Char],而不是IO[Char]。我想将结果用作公共字符串:fab=a++b;f“some”(my_shuffle“some”“)@demas:No。纯函数必须为相同的输入返回相同的结果,而
my_shuffle
显然不返回相同的结果,因此它必须位于
IO
中,以表明它是不确定的。要将它与
f
一起使用,例如,您可以编写
f“some”my\u shuffle“some”
,它将再次出现在
IO
中。另一个选项是通过将随机数生成器作为输入使其具有确定性,但您必须担心将其传递出去。@demas-您使用的是
randomRIO
,这意味着您必须返回
IO[Char]