2017-02-03 4 views
2

У меня есть эта функция в haskell, которую я хотел бы закодировать в F #, используя собственный синтаксис, а не такие функции массива, как map2.Перевести функцию слияния с Haskell на F #

Haskell:

merge [] ys = ys 
merge (x:xs) ys = x:merge ys xs 

Этот код объединяет два списка индекса мудр, как это:

INPUT: [1,2,3,4,5] [11,12,13,14] 
OUTPUT: [1,11,2,12,3,13,4,14,5] 

Я попытался сделать это в F # и получил это, но это, конечно, не компилируется:

let rec mux x y = function 
| [] -> [] 
| x::xs y::ys -> x::y::mux(xs,ys) 

Я действительно боюсь работать с двумя массивами в соответствии с шаблоном, спасибо за любые помочь вам дать.

+1

Версия haskell принимает два параметра, вы написали одно, которое принимает три. –

+0

Это списки, а не массивы. – ildjarn

ответ

4

Функция Haskell фактически не соответствует двум параметрам. Он соответствует только первому параметру и принимает второй параметр как есть.

В F #, вы можете соответствовать первому аргументу, и возвращает функцию, которая обрабатывает второй аргумент:

let rec mux = function 
    | [] -> (function ys -> ys) 
    | x::xt -> (function ys -> x :: mux ys xt) 

Но я нахожу это более ясным (и я думаю, что это более эффективно - по крайней мере, в OCaml) принимать во всех аргументах сразу, а затем проанализировать аргумент, что нужно различать на:

let rec mux xs ys = 
    match xs with 
    | [] -> ys 
    | x::xt -> x :: mux ys xt 

Если вы хотите, чтобы соответствовать по обеим переменным, было бы несколько решений. Вы можете вложить function конструкции:

let rec mux = function 
    | [] -> (function [] -> … | y::yt -> …) 
    | x::xt -> (function [] -> … | y::yt -> …) 

Но здесь я предпочитаю гнездования match конструкции:

let rec mux xs ys = 
    match xs with 
    | [] -> (match ys with 
      | [] -> … 
      | y::yt -> …) 
    | x::xt -> (match ys with 
      | [] -> … 
      | y::yt -> …) 

Кроме того, это часто лучше, чтобы соответствовать на паре входов; это зависит от того, как связаны два входа.

let rec mux xs ys = 
    match xs, ys with 
    | [], [] -> … 
    | [], y::yt -> … 
    | x::xt, [] -> … 
    | x::xt, y::yt -> … 
+0

Спасибо Жиль. Если бы я делал это так, как x :: y :: mux (xs, ys) вместо x :: mux ys xt, как бы это выглядело? Это по педагогическим причинам, потому что я изо всех сил пытаюсь понять синтаксис. – happyD

+0

@happyD Посмотри мое редактирование – Gilles

+0

Жиль, я прилагаю все усилия, чтобы попытаться заполнить пробелы, но я действительно борется. Приношу извинения за то, что ты приставал. С конструкцией функции гнезда, например, что бы я поставил вместо эллипсов? Я бы поставил [] вместо первых эллипсов и ys вместо второго, xs вместо 3-го и x :: y :: mux (xt, yt) в 4-м? – happyD

 Смежные вопросы

  • Нет связанных вопросов^_^