在Haskell中随机化列表
我试图,给定一个列表,在Haskell中创建这些元素的随机排列。我已经在Javascript中尝试了这个算法,它成功了。我是哈斯克尔的新手,所以我可能没看到什么。我很确定我收到的是单个元素,而不是只有一个元素的列表,这会使我的程序崩溃。我在以前的练习中遇到过这个问题,但仍然不知道如何解决它 该算法将列表分割,直到得到一个元素。然后有50%的几率按原样合并列表,还有50%的几率按相反的方式合并列表 代码如下:在Haskell中随机化列表,haskell,functional-programming,Haskell,Functional Programming,我试图,给定一个列表,在Haskell中创建这些元素的随机排列。我已经在Javascript中尝试了这个算法,它成功了。我是哈斯克尔的新手,所以我可能没看到什么。我很确定我收到的是单个元素,而不是只有一个元素的列表,这会使我的程序崩溃。我在以前的练习中遇到过这个问题,但仍然不知道如何解决它 该算法将列表分割,直到得到一个元素。然后有50%的几率按原样合并列表,还有50%的几率按相反的方式合并列表 代码如下: -- A randomly chosen, program-scoped constan
-- A randomly chosen, program-scoped constant from the range [1 .. 10]
randomInt :: Int
randomInt = unsafePerformIO (getStdRandom (randomR (1, 10)))
-- Divides the list in half
divideList :: [a] -> ([a], [a])
divideList list = splitAt ((length list) `div` 2) list
-- Given a list, it creates a new one with the elements of said list
randomizeList :: Eq a => a -> [a]
randomizeList list = do
let lists = (divideList list) in
if (length list) > 1
then if (randomInt > 5)
then (randomizeList (fst lists) : randomizeList (snd lists))
else (randomizeList (snd lists) : randomizeList (fst lists))
else [list]
以下是Javascript代码,以防它有所帮助:
function divideList(list){
const length = list.length / 2;
return {fst: list.splice(0, length), snd: list};
}
function randomizeList(list) {
if(list.length == 1) return list;
const lists = divideList(list);
if(Math.random() > 0.5) return randomizeList(lists.fst).concat(randomizeList(lists.snd));
else return randomizeList(lists.snd).concat(randomizeList(lists.fst));
}
提前感谢将列表随机化的快速简便方法是:
module Main where
import Control.Monad (replicateM)
import Data.Function (on)
import Data.List (sortBy)
import System.Random (randomRIO)
main :: IO ()
main = do
putStrLn "not randomized"
let nums = [1..10]
print nums
putStrLn "randomized"
print =<< randomize nums
randomize :: [a] -> IO [a]
randomize xs = do
ys <- replicateM (length xs) $ randomRIO (1 :: Int, 100000)
pure $ map fst $ sortBy (compare `on` snd) (zip xs ys)
modulemain其中
导入控制.Monad(复制项)
导入数据。函数(打开)
导入数据列表(排序)
导入系统随机(randomRIO)
main::IO()
main=do
putStrLn“非随机”
设nums=[1..10]
打印NUM
putStrLn“随机化”
打印=IO[a]
随机化xs=do
ys将列表随机化的快速简便方法是:
module Main where
import Control.Monad (replicateM)
import Data.Function (on)
import Data.List (sortBy)
import System.Random (randomRIO)
main :: IO ()
main = do
putStrLn "not randomized"
let nums = [1..10]
print nums
putStrLn "randomized"
print =<< randomize nums
randomize :: [a] -> IO [a]
randomize xs = do
ys <- replicateM (length xs) $ randomRIO (1 :: Int, 100000)
pure $ map fst $ sortBy (compare `on` snd) (zip xs ys)
modulemain其中
导入控制.Monad(复制项)
导入数据。函数(打开)
导入数据列表(排序)
导入系统随机(randomRIO)
main::IO()
main=do
putStrLn“非随机”
设nums=[1..10]
打印NUM
putStrLn“随机化”
打印=IO[a]
随机化xs=do
ys您的代码有几个问题,大部分是小错误:
签名错误,应该是randomizeList::Eq a=>[a]->[a]
(它是从一个列表到另一个列表,而不是从一个元素到另一个列表)
块开头的伪do
(只需删除)
列表与++
连接,而不是与:
连接(后者向列表中添加一个元素)
在最后一个else
中,您需要返回list
,而不是[list]
(后者是列表的列表)
以下方面应起作用:
randomizeList :: Eq a => [a] -> [a]
randomizeList list =
let lists = (divideList list) in
if (length list) > 1
then if (randomInt > 5)
then (randomizeList (fst lists) ++ randomizeList (snd lists))
else (randomizeList (snd lists) ++ randomizeList (fst lists))
else list
您的代码有几个问题,大部分是小错误:
签名错误,应该是randomizeList::Eq a=>[a]->[a]
(它是从一个列表到另一个列表,而不是从一个元素到另一个列表)
块开头的伪do
(只需删除)
列表与++
连接,而不是与:
连接(后者向列表中添加一个元素)
在最后一个else
中,您需要返回list
,而不是[list]
(后者是列表的列表)
以下方面应起作用:
randomizeList :: Eq a => [a] -> [a]
randomizeList list =
let lists = (divideList list) in
if (length list) > 1
then if (randomInt > 5)
then (randomizeList (fst lists) ++ randomizeList (snd lists))
else (randomizeList (snd lists) ++ randomizeList (fst lists))
else list
您键入的签名不正确randomizeList::Eq a=>a->[a]
接受单个元素并返回一个列表,您可能需要[a]->[a]
。我也不明白为什么需要Eq
如果键入的签名不正确randomizeList::Eq a=>a->[a]
接受单个元素并返回一个列表,您可能需要[a]->[a]
。我也不明白为什么需要Eq