0

I have a problem, where I have a record (called Probablities in my case) that only consists of a certain type, and I want to create array with the record values.

type Probability = Probability of float 
type Probabilities = {
 Pp: Probability;
 Pf: Probability;
 Pd: Probability;
 Pg: Probability; 
 }
let calculatingSum (probablities : Probabilities) =
 probablities
 // I need something, that can transform probablities to an array of Probability
 // such that I can do something like
 [|1.0;0.5|]
 |> Array.sum

I know it is possible to access all the elements individually, but I really wanna avoid that.

asked Sep 3, 2021 at 12:45
6
  • 1
    If you have to fight the type system (otherwise you'd just restructure the record and sum fields' values explicitly) then it's high time to rethink either type design (or even the language choice :)). Do you really need a record if (at least sometimes) all you need is just a list of probabilities? Commented Sep 3, 2021 at 12:54
  • ("destructure" obviously, not "restructure" - noticed too late to fix) Commented Sep 3, 2021 at 13:00
  • I reconsidering my choice of type indeed, but I would like to know if it is possible :) - The reason why records are tempting is, that I can label my probabilities and I rarely need the list, but when validating it would make the code much more condense. Worse case, I can access them individually. Commented Sep 3, 2021 at 13:00
  • You could define a static member for Probabilities type (say, AsList that would return a list of probabilities) - not sure this is any better than explicit destructuring, but maybe less verbose. Another thing that comes to mind is reflection (github.com/dotnet/fsharp/blob/main/src/fsharp/FSharp.Core/…), but looks like quite a dirty hack that should be avoided whenever it is possible... Commented Sep 3, 2021 at 13:39
  • Could you elaborate on the reason why you'd like to avoid destructuring, like @KonstantinStrukov suggests? Commented Sep 4, 2021 at 8:13

2 Answers 2

3

If I had reason to treat the data both as a record and as a collection, I would make a conversion to a map (and transform that to array or list when needed) Like so:

module Probabilities =
 let asMap (p : Probabilities) = 
 Map.ofList [
 "Pp", p.Pp
 "Pf", p.Pf
 "Pd", p.Pd
 "Pg", p.Pg
 ]
Brian Berns
17.3k2 gold badges33 silver badges45 bronze badges
answered Sep 3, 2021 at 13:54
3

You could add a method to your Probabilities type that converts its contents into an array:

type Probabilities = {
 Pp: Probability;
 Pf: Probability;
 Pd: Probability;
 Pg: Probability; 
 }
with
 member this.ToArray =
 [|
 this.Pp
 this.Pf
 this.Pd
 this.Pg
 |]

And then use it like this:

let calculatingSum (probablities : Probabilities) =
 probablities.ToArray
 |> Array.sumBy (fun (Probability p) -> p)
 |> Probability
answered Sep 3, 2021 at 14:49

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.