次のようなコードでランダムなタプルを生成できるかどうか疑問に思いました。
take 4 $ randomRs ((0,0),(70,100)) $ mkStdGen x :: [(Double,Double)]
これを試してみると、次のエラーが発生します。
No instance for (Random (Float, Float)) arising from a use of 'randoms'
使用せずにランダムタプルを取得する方法はありzip
ますか?
基本的に、エラーメッセージは、ランダムタプルを作成する定義された方法がないことを示しています。もちろん、自分で追加することもできます。
私の頭の上から(つまり、私は実際にこれをテストしていません)、あなたは次のようなことをすることができます
instance (Random x, Random y) => Random (x, y) where
randomR ((x1, y1), (x2, y2)) gen1 =
let (x, gen2) = randomR (x1, x2) gen1
(y, gen3) = randomR (y1, y2) gen2
in ((x, y), gen3)
これで、タプルで使用できますrandomR
(タプルのタイプがランダム生成をサポートしている場合)。
状態モナドを使用して、ランダムなタプルを便利に生成できます。
import Control.Applicative
import Control.Monad.State
import System.Random
randomTupleR ::
(Random a, Random b, RandomGen g)
=> (a, a)
-> (b, b)
-> g
-> ((a, b), g)
randomTupleR xb yb =
runState (liftA2 (,) (state $ randomR xb) (state $ randomR yb))