使用 random-fu shuffle 对列表进行混洗,对列表进行操作并在 Haskell 中显示结果
Shuffling a list using random-fu shuffle, doing an operation on a list and displaying result in Haskell
我的目标是从输入列表中获取 N 个随机项目的列表,并在 GHCI 中查看结果。我决定打乱输入列表,然后从中取出第一个 N 个元素(即切片第一个元素)。我正在使用来自 random-fu 模块 Data.Random.List.
的 shuffle
函数
这是我目前的代码,至少可以编译
import Data.Random
import Data.Random.List
rndSelect :: [a] -> Int -> RVar [a]
rndSelect l n
= do
l' <- shuffle l;
return $ take n l'
但是当我在 GHCI 提示符中 运行 rndSelect "abcdefg" 3
时,我得到以下错误:
<interactive>:1:1: error:
• No instance for (Show (RVar [Char]))
arising from a use of ‘print’
• In a stmt of an interactive GHCi command: print it
我想我知道这意味着什么。 RVar
不推导 Show
。我想我应该修改我的函数,以便它被打乱 RVar[a]
然后以某种方式获取第一个 N 元素的列表并将其转换为 IO 操作。
这是我失败的尝试之一:
rndSelect :: [a] -> Int -> IO ()
rndSelect l n
= do
l' <- shuffle l;
l'' <- take n l'
s <- runRVar l'' StdRandom
putStrLn s
我知道,它一团糟,并且在错误之上引发错误。我是 Monads 的初学者,在 Haskell
中“做”积木之类的事情
如果有人帮助我修正我的方法,我会很高兴,但如果你知道实现我的目标的替代方法,我也会很高兴看到它。非常感谢!
您的 rndSelect :: [a] -> Int -> RVar [a]
完全没问题,但很明显结果 RVar [a]
无法真正显示。毕竟这是一个概率分布。这种分布通常“包含”无限多可能的结果。您所希望做的就是从分布中显示 samples。由于 GHCi 允许您进行 IO,因此很容易在那里获得样本:
*Main> sample $ rndSelect "abcdefg" 3
"def"
*Main> sample $ rndSelect "abcdefg" 3
"ecb"
*Main> sample $ rndSelect "abcdefg" 3
"fbc"
*Main> :m +Control.Monad
*Main Control.Monad> sample . replicateM 20 $ rndSelect "abcdefg" 3
["gef","adf","cga","bfd","eab","bgd","gdf","abg","egc","bda","ceb","fbd","agb","egc","acb","bga","gbd","edb","egb","egd"]
我的目标是从输入列表中获取 N 个随机项目的列表,并在 GHCI 中查看结果。我决定打乱输入列表,然后从中取出第一个 N 个元素(即切片第一个元素)。我正在使用来自 random-fu 模块 Data.Random.List.
的shuffle
函数
这是我目前的代码,至少可以编译
import Data.Random
import Data.Random.List
rndSelect :: [a] -> Int -> RVar [a]
rndSelect l n
= do
l' <- shuffle l;
return $ take n l'
但是当我在 GHCI 提示符中 运行 rndSelect "abcdefg" 3
时,我得到以下错误:
<interactive>:1:1: error:
• No instance for (Show (RVar [Char]))
arising from a use of ‘print’
• In a stmt of an interactive GHCi command: print it
我想我知道这意味着什么。 RVar
不推导 Show
。我想我应该修改我的函数,以便它被打乱 RVar[a]
然后以某种方式获取第一个 N 元素的列表并将其转换为 IO 操作。
这是我失败的尝试之一:
rndSelect :: [a] -> Int -> IO ()
rndSelect l n
= do
l' <- shuffle l;
l'' <- take n l'
s <- runRVar l'' StdRandom
putStrLn s
我知道,它一团糟,并且在错误之上引发错误。我是 Monads 的初学者,在 Haskell
中“做”积木之类的事情如果有人帮助我修正我的方法,我会很高兴,但如果你知道实现我的目标的替代方法,我也会很高兴看到它。非常感谢!
您的 rndSelect :: [a] -> Int -> RVar [a]
完全没问题,但很明显结果 RVar [a]
无法真正显示。毕竟这是一个概率分布。这种分布通常“包含”无限多可能的结果。您所希望做的就是从分布中显示 samples。由于 GHCi 允许您进行 IO,因此很容易在那里获得样本:
*Main> sample $ rndSelect "abcdefg" 3
"def"
*Main> sample $ rndSelect "abcdefg" 3
"ecb"
*Main> sample $ rndSelect "abcdefg" 3
"fbc"
*Main> :m +Control.Monad
*Main Control.Monad> sample . replicateM 20 $ rndSelect "abcdefg" 3
["gef","adf","cga","bfd","eab","bgd","gdf","abg","egc","bda","ceb","fbd","agb","egc","acb","bga","gbd","edb","egb","egd"]