开发者

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

开发者 https://www.devze.com 2023-04-04 05:44 出处:网络
type Range = int * int type Domain = Range array type Gene = int type Individual = Gene array type Population = Individual array
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 do开发者_Go百科main)

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?


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|]|]


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)


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)
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号