F# 如何创建一个;配对;要与字符串列表匹配的函数?

F# 如何创建一个;配对;要与字符串列表匹配的函数?,f#,F#,我正在(滚动到底部)上做一个练习,创建一个Pair方法 我能够毫无问题地对整数列表进行配对,但对字符串列表引发了F#异常。对于我这样的F#初学者来说,破译例外意味着什么对我来说太神秘了 下面是我在fsi.exe > let pair l = - let rec loop acc = function - | [] -> acc - | (hd1 :: hd2 :: tl) -> loop ((hd1, hd2) :: acc) tl -

我正在(滚动到底部)上做一个练习,创建一个
Pair
方法

我能够毫无问题地对整数列表进行配对,但对字符串列表引发了F#异常。对于我这样的F#初学者来说,破译例外意味着什么对我来说太神秘了

下面是我在
fsi.exe

> let pair l =
-     let rec loop acc = function
-         | [] -> acc
-         | (hd1 :: hd2 :: tl) -> loop ((hd1, hd2) :: acc) tl
-     List.rev(loop [] l)
-
- printfn "%A" ([1..10] |> pair)
- printfn "%A" ([ "one"; "two"; "three"; "four"; "five" ] |> pair);;

      let rec loop acc = function
  -----------------------^

stdin(2,24): warning FS0025: Incomplete pattern matches on this expression. 
    For example, the value '[_]' will not be matched

val pair : 'a list -> ('a * 'a) list

[(1, 2); (3, 4); (5, 6); (7, 8); (9, 10)]
Microsoft.FSharp.Core.MatchFailureException: 
Exception of type 'Microsoft.FSharp.Core.MatchFailureException' was thrown.
   at FSI_0002.clo@2T.Invoke(List`1 acc, List`1 _arg1)
   at FSI_0002.pair[T](List`1 l)
   at <StartupCode$FSI_0002>.$FSI_0002._main()
stopped due to error
指示
Pair
在通用列表上操作。

问题:那么为什么
Pair
不能处理字符串列表

[答案](我的版本)
简单地返回
的累积列表,否则
案例(u)就成功了。
警告也得到了处理

let pair l =
    let rec loop acc = function
//        | [] -> acc
        | (hd1 :: hd2 :: tl) -> loop ((hd1, hd2) :: acc) tl
        | _ -> acc
    List.rev(loop [] l)

printfn "%A" ([1..10] |> pair)
printfn "%A" ([ "one"; "two"; "three"; "four"; "five" ] |> pair)
[EDIT2]为了完整起见,我还将发布我的
Unpair
版本。

let unpair l = [for (a,b) in l do yield! a :: b :: []]
对于100万个项目列表,使用解决方案版本与我的解决方案版本进行基准测试存在一些缺陷

#light

open System;

let pn l = printfn "%A" l

let duration f = 
    let startTime = DateTime.Now;
    let returnValue = f()
    let endTime = DateTime.Now;
    printfn "Duration (ms): %f" (endTime - startTime).TotalMilliseconds
    returnValue

let ll =  [for a in 1..1000000 do yield (a)]
let tl = [for a in 1..1000000 do yield (a,a)]


let pair1 l =
    let rec loop acc = function
        | [] | [_] -> List.rev acc
        | h1 :: h2 :: tl -> loop ((h1, h2) :: acc) tl
    loop [] l

let unpair1 l =
    let rec loop acc = function
        | [] -> List.rev acc
        | (h1, h2) :: tl -> loop (h2 :: h1 :: acc) tl
    loop [] l

let pair2 l =
    let rec loop acc = function
        | (hd1 :: hd2 :: tl) -> loop ((hd1, hd2) :: acc) tl
        | _ | [_] -> acc
    List.rev(loop [] l)

    let unpair2 l = [for (a,b) in l do yield! a :: b :: []]

pn(duration (fun() -> ll |> pair1))
pn(duration (fun() -> tl |> unpair1))

pn(duration (fun() -> ll |> pair2))
pn(duration (fun() -> tl |> unpair2))
基准结果:

Solution version
PAIR -> Duration (ms): 255.000000
UNPAIR -> Duration (ms): 840.000000

My version
PAIR -> Duration (ms): 220.000000
UNPAIR -> Duration (ms): 1624.000000

我不认为你的配对版本在一个单数的列表上有效。您碰巧测试了偶数个整数和奇数个字符串。我认为你的第二个匹配论点意味着至少有两名成员。因此,您将中断2中断2,并得到一个包含1个元素的列表,并且所有条件都不匹配


[\]是一个包含任何内容的1项列表。您必须提供一个与之匹配的谓词。

我认为您的Pair版本在奇数的列表上不起作用。您碰巧测试了偶数个整数和奇数个字符串。我认为你的第二个匹配论点意味着至少有两名成员。因此,您将中断2中断2,并得到一个包含1个元素的列表,并且所有条件都不匹配


[\]是一个包含任何内容的1项列表。您必须提供与之匹配的谓词。

顺便说一句,Wiki book列出了实现“Pair”的解决方案,但我决定不作弊。顺便说一句,Wiki book列出了实现“Pair”的解决方案,但我决定不作弊。我只返回了“else”情况下返回的任何累计值。它起作用了!谢谢-答案贴在问题中。我只是返回了“else”案例中返回的累积值。它起作用了!谢谢-答案张贴在问题中。
Solution version
PAIR -> Duration (ms): 255.000000
UNPAIR -> Duration (ms): 840.000000

My version
PAIR -> Duration (ms): 220.000000
UNPAIR -> Duration (ms): 1624.000000