函数返回两个输出

Wor*_*ice 3 f# function

我想创建一个产生两个输出的函数.请考虑以下示例:

我建立了两个函数,给定一个整数列表,返回偶数位置的元素列表和奇数位置的元素.

let rec alternate1 lst =
    match lst with
    [] -> []
    | [x] -> []
    | x::y::xs -> y::(alternate1 xs)

let rec alternate2 lst =
    match lst with
    [] -> []
    | [x] -> [x]
    | x::y::xs -> x::(alternate2 xs)
Run Code Online (Sandbox Code Playgroud)

这里一切都很好.现在的问题:我想创建一个单一的功能alternate与签名返回这两个列表alternate: int list-> (int list * int list).

let rec alternate lst =
    match lst with 
    [] -> []
    | [x] -> []
    | [x::y] -> [y]
    (*My attempts:*)
    | x::y::xs -> ((y::alternate xs),  (x::alternate xs))
    | x::y::xs -> [(y::alternate xs);  (x::alternate xs)]
    | x::y::xs -> ((y::alternate xs) && (x::alternate xs))
Run Code Online (Sandbox Code Playgroud)

到目前为止,还没有解决方案.我很确定问题甚至是愚蠢的,但我的参考并没有帮助我解决问题.

Fyo*_*kin 6

既然你调用alternate递归,递归调用会返回你两个输出,所以你当然不能把那个元组的列表-作为y::alternate xs.

你必须首先分开元组,分别处理这些部分,然后在返回之前将它们重新组合成一个元组:

let nextXs, nextYs = alternate xs
x::nextXs,  y::nextYs
Run Code Online (Sandbox Code Playgroud)

然后,你的基本情况也应该返回两个输出 - 否则你的函数有不明确的返回类型:

| [] -> [], []
| [x] -> [x], []
| [x; y] -> [x], [y]
Run Code Online (Sandbox Code Playgroud)

(另请注意,您的匹配大小写[x::y]实际上匹配列表列表,其中包含一个列表,其中第一个元素将被命名x,列表的尾部将被命名y.为了匹配两个元素的列表,使用[x; y]x::y::[])

将它们组合在一起:

let rec alternate lst =
    match lst with 
    | [] -> [], []
    | [x] -> [x], []
    | [x; y] -> [x], [y]
    | x::y::rest ->
        let nextXs, nextYs = alternate rest
        x::nextXs,  y::nextYs
Run Code Online (Sandbox Code Playgroud)

另外:从技术上讲,[x; y]不需要基本情况​​,因为它会被最后一种情况所覆盖.