我的代码旨在创建一个单词搜索难题。有一个称为“方向”的数据表示拼图中每个单词的方向。
data Orientation =
Forward | Back | Up | Down | UpForward | UpBack | DownForward | DownBack
deriving (Eq, Ord, Show, Read)
现在给定一个字符串输入[String]
,我想随机分配每个字符串一个方向,例如[(Orientation, String)]
assignWordDir :: [String] -> [(Orientation, String)]
assignWordDir [] = []
assignWordDir (s:strs) = (ori, s) : assignWordDir
where ori = pickOri [Forward, Back, Up, Down, UpForward, UpBack, DownForward, DownBack]
pickOri :: [a] -> IO a
pickOri xs = do
i <- randomRIO (0, len)
pure $ xs !! i
where len = length xs - 1
由于pickOri
is的输出,我无法编译IO Orientation
,是否有关于如何修改代码的建议?非常感谢
Couldn't match expected type ‘[(IO Orientation, String)]’
with actual type ‘[String] -> [(Orientation, String)]’
您可能会考虑修改函数,以便通过获取RandomGen
参数使它们保持纯净。pickOri
例如,可以对函数进行如下修改:
pickOri :: RandomGen g => g -> [a] -> (a, g)
pickOri rnd xs =
let len = length xs - 1
(i, g) = randomR (0, len) rnd
in (xs !! i, g)
必须将新RandomGen
值g
与选定的列表元素一起返回,以便下次将生成另一个伪随机数。
同样,您可以这样修改assignWordDir
:
assignWordDir :: RandomGen g => g -> [b] -> [(Orientation, b)]
assignWordDir _ [] = []
assignWordDir rnd (s:strs) = (ori, s) : assignWordDir g strs
where (ori, g) =
pickOri rnd [Forward, Back, Up, Down, UpForward, UpBack, DownForward, DownBack]
请注意,assignWordDir
递归到时,递归函数调用将使用从g
接收的pickOri
。
您可以使用mkStdGen
或newStdGen
产生RandomGen
值。这是一个使用示例newStdGen
:
*Q65132918> rnd <- newStdGen
*Q65132918> assignWordDir rnd ["foo", "bar", "baz"]
[(UpBack,"foo"),(Up,"bar"),(UpBack,"baz")]
*Q65132918> assignWordDir rnd ["foo", "bar", "baz"]
[(UpBack,"foo"),(Up,"bar"),(UpBack,"baz")]
请注意,当您使用相同的 RandomGen
值时,您将获得相同的序列。那是因为assignWordDir
是一个纯函数,所以这是预料之中的。
但是,您可以通过创建或获取新StdGen
值来产生新的随机序列:
*Q65132918> rnd <- newStdGen
*Q65132918> assignWordDir rnd ["foo", "bar", "baz"]
[(Up,"foo"),(Up,"bar"),(Forward,"baz")]
如果要在已编译的模块中使用此功能,则可以保留此处显示的这些功能,然后在入口点将其与newStdGen
-generatedStdGen
一起使用main
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句