如何在SML中获取自定义数据类型的随机值?

如何在SML中获取自定义数据类型的随机值?,sml,smlnj,Sml,Smlnj,如何为下面这样的数据类型返回随机值 datatype rank = Jack | Queen | King | Ace | Num of int datatype rank = Jack | Queen | King | Ace | Num of int 我正在处理一个函数,生成一个随机卡片列表,以便输入到另一个函数,因此也需要一个类似的函数 输出应该是杰克、金等符号,或者是2到9之间的整数 以下代码不正确: fun pick_rank() = case Random.randRang

如何为下面这样的数据类型返回随机值

datatype rank = Jack | Queen | King | Ace | Num of int
datatype rank = Jack | Queen | King | Ace | Num of int
我正在处理一个函数,生成一个随机卡片列表,以便输入到另一个函数,因此也需要一个类似的函数

输出应该是杰克、金等符号,或者是2到9之间的整数

以下代码不正确:

fun pick_rank() =
   case Random.randRange(2,13)  of 13 => Ace
               | 12 => King
               | 11 => Queen
               | 10 => Jacl
               | Int v => v
如何为下面这样的数据类型返回随机值

datatype rank = Jack | Queen | King | Ace | Num of int
datatype rank = Jack | Queen | King | Ace | Num of int
我有两个答案:要么生成唯一的每个值,要么生成所有可能的值,对它们进行洗牌,然后选择一个。如果你只想要一个独立的随机变量,前者是最简单的。但是如果你想模拟一个纸牌游戏,在这个游戏中不可能两次抽同一张牌,那么你可能需要洗牌

你可以看到我是怎么做的。我将在这里重复这两种方法:

(* There are 13 card ranks, 4 suits *)
datatype rank
  = Ace | Two | Three | Four | Five | Six | Seven
  | Eight | Nine | Ten | Jack | Queen | King

datatype suit = Hearts | Clubs | Diamonds | Spades

datatype card = Card of suit * rank

fun concatMap f xs = List.concat (List.map f xs)
fun product xs ys = concatMap (fn x => map (fn y => (x,y)) ys) xs

val allCards = map Card
  (product
     [Hearts,Clubs,Diamonds,Spades]
     [Ace,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Jack,Queen,King])

(* Create a new pseudo-random number generator, prng *)
val prng = Random.newgen ()

(* rlist determines a random index in [0 ; length xs[. *)
fun rlist xs = Random.range (0, length xs) prng

(* remove removes the n'th element of a list *)
fun remove (_, []) = raise Domain
  | remove (0, card::library) = library
  | remove (n, card::library) = card::remove (n-1, library);

(* randomtake removes and returns the i'th (random) element of a list *)
fun randomtake library =
    let val i = rlist library
        val card = List.nth (library, i)
        val rest = remove (i, library)
    in
      (card, rest)
    end

(* Shuffling is done by removing random cards until there are no cards left *)
fun shuffle [] = []
  | shuffle cards =
    let val (c,r) = randomtake cards
    in
      c :: shuffle r
    end
使用这些函数,您可以通过随机抽取所有卡片来挑选一张随机卡片,或者您可以通过先洗牌所有卡片并挑选顶部元素来挑选任意数量的随机卡片,而不必挑选同一张卡片

请注意,这些都不是有效的方法。作为练习,您可以实现

如何为下面这样的数据类型返回随机值

datatype rank = Jack | Queen | King | Ace | Num of int
datatype rank = Jack | Queen | King | Ace | Num of int
我有两个答案:要么生成唯一的每个值,要么生成所有可能的值,对它们进行洗牌,然后选择一个。如果你只想要一个独立的随机变量,前者是最简单的。但是如果你想模拟一个纸牌游戏,在这个游戏中不可能两次抽同一张牌,那么你可能需要洗牌

你可以看到我是怎么做的。我将在这里重复这两种方法:

(* There are 13 card ranks, 4 suits *)
datatype rank
  = Ace | Two | Three | Four | Five | Six | Seven
  | Eight | Nine | Ten | Jack | Queen | King

datatype suit = Hearts | Clubs | Diamonds | Spades

datatype card = Card of suit * rank

fun concatMap f xs = List.concat (List.map f xs)
fun product xs ys = concatMap (fn x => map (fn y => (x,y)) ys) xs

val allCards = map Card
  (product
     [Hearts,Clubs,Diamonds,Spades]
     [Ace,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Jack,Queen,King])

(* Create a new pseudo-random number generator, prng *)
val prng = Random.newgen ()

(* rlist determines a random index in [0 ; length xs[. *)
fun rlist xs = Random.range (0, length xs) prng

(* remove removes the n'th element of a list *)
fun remove (_, []) = raise Domain
  | remove (0, card::library) = library
  | remove (n, card::library) = card::remove (n-1, library);

(* randomtake removes and returns the i'th (random) element of a list *)
fun randomtake library =
    let val i = rlist library
        val card = List.nth (library, i)
        val rest = remove (i, library)
    in
      (card, rest)
    end

(* Shuffling is done by removing random cards until there are no cards left *)
fun shuffle [] = []
  | shuffle cards =
    let val (c,r) = randomtake cards
    in
      c :: shuffle r
    end
使用这些函数,您可以通过随机抽取所有卡片来挑选一张随机卡片,或者您可以通过先洗牌所有卡片并挑选顶部元素来挑选任意数量的随机卡片,而不必挑选同一张卡片


请注意,这些都不是有效的方法。作为练习,您可以实施。

这是否回答了您的问题?Int v=>v应该是v=>Num v这能回答你的问题吗?Int v=>v应该是v=>Num v是否可以仅针对suit=Spades | Clubs | Hearts | Diamonds的情况给出一个示例?我想我可以按原样使用代码,在列表中以suit*rank的形式填写n次卡片。该示例将证明当前示例没有演示什么?是否可以仅针对suit=Spades | Clubs | Hearts | Diamonds的情况给出一个示例?我想我可以按原样使用代码,在列表中以suit*rank的形式填写n次卡片。该示例会证明当前示例没有演示什么?