2017-02-03 20 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

吉尔斯,我尽我所能努力填补空白,但我真的很挣扎。我很抱歉要纠缠。 例如,使用嵌套函数构造,我会用什么来代替椭圆?我会把[]代替第一个椭圆和y而不是第二个,而不是第三个和x :: y :: mux(xt,yt)在第四个? – happyD