定义OCaml类型结构

定义OCaml类型结构,ocaml,Ocaml,我是OCaml新手,我正在尝试定义一种类型来制作一副卡片,我现在拥有的是: type palo = Espada | Basto | Oro | Copa type valor = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 type carta = Carta of palo*valor 我想知道的是,是否有一种方法,我可以将一副牌定义为一系列的卡塔牌,每一种组合都有帕洛-瓦罗牌,然后“洗牌”它 事先非常感谢 编辑: 我可能应该澄清一下,

我是OCaml新手,我正在尝试定义一种类型来制作一副卡片,我现在拥有的是:

type palo = Espada | Basto | Oro | Copa
type valor = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12
type carta = Carta of palo*valor
我想知道的是,是否有一种方法,我可以将一副牌定义为一系列的卡塔牌,每一种组合都有帕洛-瓦罗牌,然后“洗牌”它

事先非常感谢

编辑:
我可能应该澄清一下,这是一副西班牙牌,这就是为什么没有杰克、皇后、国王或王牌的原因。当然,你可以用

因此,您可以创建一个长度
12*4=48
卡的数组,然后将其洗牌(您可以在中找到此洗牌代码),然后使用
array.to_list
如果您想保留一个卡列表而不是数组

[编辑] 我冒昧地改写了你的类型:

type palo = Espada | Basto | Oro | Copa
type valor = Uno | Dos | Tres | Quatro | Cinco | Seis | Siete | 
             Ocho | Nueve | Diez | Once | Doce
type carta = palo * valor
您不需要说
carta
是一个
carta of palo*valor
,因为您只有一个构造函数;-)
carta
将是这对夫妇的别名
palo*valor

但是,实际上,最简单的方法是使用以下类型:

type palo = Espada | Basto | Oro | Copa
type valor = int
type carta = palo * valor
例如,为了确保你的勇气不能超过12。这将使卡片的制作更加容易。(例如,这样做:

let cards = Array.init 48 (fun i -> 
   let palo = 
     if i < 12 then Espada
     else if i < 24 then Basto 
     else if i < 36 then Oro 
     else  Copa
   in palo, i mod 12 + 1
  )
如您所见,我创建了一个valor列表,并为每个
palo
添加
palo
到该列表的每个元素中(因为列表是持久数据结构,它给了我一个新列表,它不修改前一个列表),然后连接四个列表

还有一个更好的方法:

type palo = Espada | Basto | Oro | Copa
type valor = Uno | Dos | Tres | Quatro | Cinco | Seis | Siete | 
             Ocho | Nueve | Diez | Once | Doce
type carta = palo * valor

let lv = [Uno; Dos; Tres; Quatro; Cinco; Seis; Siete; 
          Ocho; Nueve; Diez; Once; Doce]

let cards = 
  let new_list p = List.map (fun v -> p, v) lv in
  let l1 = new_list Espada in
  let l2 = new_list Basto in
  let l3 = new_list Oro in
  let l4 = new_list Copa in
  List.rev_append l1 (List.rev_append l2 (List.rev_append l3 l4))
let lp = [Espada; Basto; Oro; Copa]

let cardsb = 
  let new_list p = List.map (fun v -> p, v) lv in
  List.fold_left (fun acc p ->
    List.rev_append (new_list p) acc) [] lp
它使用迭代器,非常漂亮,非常迷人


最后这些方法的问题是,您无法确定是否将所有构造函数都放在了列表中,并且键入系统不会对此发出警告。:-(

当然,您可以通过

因此,您可以创建一个长度
12*4=48
卡的数组,然后将其洗牌(您可以在中找到此洗牌代码),然后使用
array.to_list
如果您想保留一个卡列表而不是数组

[编辑] 我冒昧地改写了你的类型:

type palo = Espada | Basto | Oro | Copa
type valor = Uno | Dos | Tres | Quatro | Cinco | Seis | Siete | 
             Ocho | Nueve | Diez | Once | Doce
type carta = palo * valor
你不需要说
carta
是一个
carta of palo*valor
,因为你只有一个构造函数;-)
carta
将是这对夫妇的别名
palo*valor

但是,实际上,最简单的方法是使用以下类型:

type palo = Espada | Basto | Oro | Copa
type valor = int
type carta = palo * valor
例如,为了确保你的勇气不能大于12,这将使卡的创建更加容易。(例如,这样做:

let cards = Array.init 48 (fun i -> 
   let palo = 
     if i < 12 then Espada
     else if i < 24 then Basto 
     else if i < 36 then Oro 
     else  Copa
   in palo, i mod 12 + 1
  )
如您所见,我创建了一个valor列表,并为每个
palo
添加
palo
到该列表的每个元素中(因为列表是持久数据结构,它给了我一个新列表,它不修改前一个列表),然后连接四个列表

还有一个更好的方法:

type palo = Espada | Basto | Oro | Copa
type valor = Uno | Dos | Tres | Quatro | Cinco | Seis | Siete | 
             Ocho | Nueve | Diez | Once | Doce
type carta = palo * valor

let lv = [Uno; Dos; Tres; Quatro; Cinco; Seis; Siete; 
          Ocho; Nueve; Diez; Once; Doce]

let cards = 
  let new_list p = List.map (fun v -> p, v) lv in
  let l1 = new_list Espada in
  let l2 = new_list Basto in
  let l3 = new_list Oro in
  let l4 = new_list Copa in
  List.rev_append l1 (List.rev_append l2 (List.rev_append l3 l4))
let lp = [Espada; Basto; Oro; Copa]

let cardsb = 
  let new_list p = List.map (fun v -> p, v) lv in
  List.fold_left (fun acc p ->
    List.rev_append (new_list p) acc) [] lp
它使用迭代器,非常漂亮,非常迷人



最后这些方法的问题是,您无法确定是否将所有构造函数都放在了列表中,并且键入系统不会对此发出警告。:-(

您的类型valor真的被接受了吗?我严重怀疑,因为它没有语法:type t=C of type;-)如果答案对您来说合适,请不要忘记接受它。;-)@Lhooq我该怎么办?抱歉,但我也是stackoverflow的新手,谢谢。答案很棒。你没有可以点击我答案左边的东西吗?你的类型valor真的被接受了吗?我很怀疑,因为它没有语法:type t=C of type;-)如果答案适合你,别忘了接受它。;-)@我该怎么办?对不起,我也是stackoverflow的新手,谢谢,答案很好,你没有可以点击我答案左边的东西吗?非常感谢,正如我之前提到的,我是一个新手,所以现在少了一个问题,我现在就修改它。这是一个典型的面向类型的练习,见@Str我以为你的评论是关于我的解决方案和我的构造函数列表,但不是,是关于卡的问题。;-)@不好意思,我刚去了讨论的地方。希望你也觉得它有趣,我想这本书是2001年的。@Str哦,别担心,我已经读了很多遍了,但我想尝试适应Jenaro的特定类型;-)但从你的评论中,我认为我错过了解决方案,我很难过地发现并非如此-D非常感谢你,正如我前面提到的,我是一个新手,所以现在不用担心一个问题,我现在就修改它。这是面向类型的练习中的一个经典,请看@Str。我以为你的评论是关于我的解决方案和我的构造函数列表,但不是,是关于卡片问题。;-)@不好意思,我刚去了讨论的地方。希望你也觉得它有趣,我想这本书是2001年的。@Str哦,别担心,我已经读了很多遍了,但我想尝试适应Jenaro的特定类型;-)但从你的评论中,我认为我错过了解决方案,我很难过地发现并非如此-D