devoured elysium
devoured elysium

Reputation: 105037

Refactoring F# function to make use of forward-pipe operator

type Range = int * int
type Domain = Range array

type Gene = int
type Individual = Gene array
type Population = Individual array

let genPop (domain:Domain) popSize =
  let genInd (domain:Domain) : Individual =
    let genGene (range:Range) = genNum (fst range) (snd range)
    Array.map genGene domain
  Array.init popSize (fun _ -> genInd domain)

So, a Population is nothing more than an array of Individuals. Each Individual consists of an array of Genes, that are nothing more than an alias for integers. genNum will just generate a random integer for us.

I am not particularly happy with my genPop implementation. Although it works fine and as expected, I'd like to try out an implementation that'd made use of the forward pipe operator |>, instead of those sub functions.

Any tips on how to proceed on this? Ideally I'd say that one could start of with popSize, that would be transformed into a Population, that'd have as its members Individuals that'd consist of Genes. The problem is that we generally need to do things the other way around. We first need to create the Genes, and then the Individuals, and only then we can have a Population!

How would you implement this (other than the way I did it)? Maybe there are other ways that are not currently apparent to me?

Upvotes: 4

Views: 234

Answers (3)

Ramon Snir
Ramon Snir

Reputation: 7560

Here is my (second) try:

let genPop (domain : Domain) popSize : Individual [] =
    (fun _ ->
    domain
    |> Array.map (fun (a, b) -> genNum a b))
    |> Array.init popSize
    |> Array.map (Array.copy)

Upvotes: 1

Ankur
Ankur

Reputation: 33637

The function can be reduced to (using pipe):

let uncurry f = fun(a,b) -> f a b //Helper function

let genPop (domain:Domain) popSize : Population  =
  (fun _ -> domain)
  |> Array.init popSize 
  |> Array.map ((uncurry genNum) |> Array.map)

Upvotes: 1

J D
J D

Reputation: 48687

Replace fst and snd with pattern matching:

let genGene (x, y) = genNum x y

Your whole function can become:

let genPop domain popSize =
  Array.init popSize (fun _ -> Array.map (fun (x, y) -> genNum x y) domain)

or:

let genPop domain popSize =
  [|for _ in 1..popSize ->
      [|for x, y in domain ->
          genNum x y|]|]

Upvotes: 5

Related Questions