我正在使用 F# 对掷骰子进行一些蒙特卡罗模拟,我使用整数来表示单次掷骰子,并使用整数列表来表示掷骰子列表。我希望能够将掷骰子而不是整数建模为一种类型。我只使用 6 面骰子,我想要一种类型,它具有别名/同义词类型的一些特征以及可区分联合或枚举的一些属性。
这些是我希望在我的类型上看到的
我尝试了上面列出的类型的组合,但似乎都有一些缺点(这可能是我的用法和理解,而不是类型本身)。
这只是我为了好玩(不是利润)而做的事情的一个小例子,但我想看到一个答案,因为我可以想象在更严肃的数据建模中使用它。
最佳答案
似乎带有一些静态方法的 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]
Gist of just the code
关于f# - 在 F# 中建模掷骰子,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26737560/