Рефакторинг функции F # для использования оператора forward-pipe - PullRequest
4 голосов
/ 09 сентября 2011
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)

Итак, Population - это не более чем массив Individual с.Каждый Individual состоит из массива Gene s, которые являются не более чем псевдонимом для целых чисел.genNum просто сгенерирует для нас случайное целое число.

Я не особенно доволен своей реализацией genPop.Хотя он работает нормально и, как и ожидалось, я хотел бы попробовать реализацию, в которой вместо этих подфункций использовался оператор прямой трубы |>.

Любые советы о том, как продолжитьэтот?В идеале я бы сказал, что можно начать с popSize, который будет преобразован в население, в состав которого войдут люди, состоящие из генов.Проблема в том, что нам, как правило, нужно делать все наоборот.Сначала нам нужно создать гены, а затем отдельных людей, и только тогда у нас будет популяция!

Как бы вы это реализовали (кроме того, как я это сделал)?Может быть, есть другие способы, которые в настоящее время не очевидны для меня?

Ответы [ 3 ]

5 голосов
/ 09 сентября 2011

Заменить fst и snd на сопоставление с образцом:

let genGene (x, y) = genNum x y

Вся ваша функция может стать:

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

или

let genPop domain popSize =
  [|for _ in 1..popSize ->
      [|for x, y in domain ->
          genNum x y|]|]
1 голос
/ 09 сентября 2011

Вот моя (вторая) попытка:

let genPop (domain : Domain) popSize : Individual [] =
    (fun _ ->
    domain
    |> Array.map (fun (a, b) -> genNum a b))
    |> Array.init popSize
    |> Array.map (Array.copy)
1 голос
/ 09 сентября 2011

Функция может быть уменьшена до (с использованием трубы):

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