我正在使用F#对骰子卷进行一些蒙特卡罗模拟,我使用整数来表示一个骰子的卷和一个整数列表来表示骰子卷列表。我希望能够模拟骰子卷而不是整数作为一种类型。我只使用6面骰子,我希望这种类型具有Alias / Synonym类型的一些特性以及Discriminated Union或Enum的一些属性。
这些是我希望在我的类型上看到的
我尝试过上面列出的类型组合,但似乎都有一些缺点(这可能是我的用法和理解,而不是类型本身)。
这只是我为了娱乐而做的事情的一个微不足道的例子(不是利润),但我希望能够在更严肃的数据建模中看到答案。
答案 0 :(得分:4)
作为其中一个选项,您可以创建自己的数字类型,如Tomas Petricek在本文中所述: http://tomasp.net/blog/fsharp-custom-numeric.aspx/index.html
答案 1 :(得分:3)
似乎是一个带有一些静态方法的Discriminated Union可以处理你想要的一切
open System
type D6 =
| One | Two | Three | Four | Five | Six
member self.Value =
match self with
| One -> 1 | Two -> 2 | Three -> 3
| Four -> 4 | Five -> 5 | Six -> 6
override self.ToString() =
match self with
| One -> "One" | Two -> "Two" | Three -> "Three"
| Four -> "Four" | Five -> "Five" | Six -> "Six"
static member Create (num:int) =
match num with
| 1 -> One | 2 -> Two | 3 -> Three
| 4 -> Four | 5 -> Five | 6 -> Six
| _ -> failwithf "Could not create D6, %d is not in range 1-6" num
static member inline Roll() = Random().Next(1,7) |> D6.Create
调用D6.Roll()将生成单个随机滚动
> D6.Roll();; val it : D6 = Four
> D6.Roll();; val it : D6 = Six
> D6.Roll();; val it : D6 = Two
> D6.Roll();; val it : D6 = Five
您可以创建静态成员和操作符,以便轻松组合D6
static member inline Add (a:D6) (b:D6) = a.Value + b.Value
static member inline (+) (a , b ) = D6.Add a b
static member inline Subtract (a:D6) (b:D6) = a.Value - b.Value
static member inline (-) (a , b ) = D6.Subtract a b
静态成员,可以轻松地从输入列表
创建它们 static member FromList (numls: int list ) =
numls |> List.map D6.Create
比较使用此类型的框
D6.One > D6.Two;;
val it : bool = false
D6.One < D6.Two;;
val it : bool = true
无限序列可以轻松生成随机输入
let rollGen =
let rnd = Random()
let rec gen() = seq { yield rnd.Next(1,7)
yield! gen() }
gen()
> rollGen;;
val rollGen : seq<int>
可以映射以创建无限随机序列D6
let d6Gen = rollGen |> Seq.map D6.Create
> d6Gen;;
val d6Gen : seq<D6>
如果你想拉出一个静态的输入值列表,你可以从随机无限序列中重复使用,你需要使用像
这样的函数let rollList num = rollGen |> Seq.take num |> List.ofSeq
let d6List num = d6Gen |> Seq.take num |> List.ofSeq ;;
let _20rolls = rollList 20 ;;
> val _20rolls : int list =
[3; 4; 2; 3; 5; 6; 4; 6; 6; 6; 5; 3; 4; 3; 2; 1; 2; 5; 3; 6]*)
let _30d6 = d6List 30 ;;
> val _30d6 : D6 list =
[Two; Six; One; Three; Two; Three; One; One; Six; Six; Four; Four; Three;
Four; One; Five; Three; Four; Four; Four; Three; Two; Six; Four; One; Three;
One; Five; Two; Two]