4

F# 中是否有多个实例模式?

考虑一下我正在处理一个列表。我有以下模式匹配

match l with
| [] | [_] -> l  //if the list is empty or contains only one item, simply return it
|        

    //is there a pattern to test if all of the elements are identical?

换句话说,传递 [] 或 [1] 应该简单地返回列表,因此应该 [1;1;1;...] 但我不知道如何模式匹配最后一个模式。这可能吗?或者有没有更好的方法可以使用?我在任何地方都没有发现任何关于重复模式的信息。

4

3 回答 3

8

我不知道有什么模式可以满足您的要求,但是您可以这样做:

let allSame L =
    match L with
    | [] | [_] -> L
    | h::t when t |> List.forall ((=) h) -> L
    | _ -> failwith "unpossible!" //handle the failing match here

PS你在谈论一个序列,但你的匹配表明你正在使用一个列表。序列的相应代码将类似于

let allSameSeq s = 
    match Seq.length s with
    | 0 | 1 -> s
    | _ when Seq.skip 1 s |> Seq.forall ((=) (Seq.head s)) -> s
    | _ -> failwith "unpossible!"

请注意,此功能的性能可能比基于列表的功能更差。

于 2009-10-29T11:10:48.333 回答
4

这是使用多案例活动模式的解决方案。

let (|SingleOrEmpty|AllIdentical|Neither|) (lst:'a list) =
    if lst.Length < 2 then
        SingleOrEmpty
    elif List.forall (fun elem -> elem = lst.[0]) lst then
        AllIdentical
    else
        Neither

let allElementsIdentical lst:'a list =
    match lst with
    |SingleOrEmpty|AllIdentical -> lst
    |Neither -> failwith "Not a suitable list"
于 2009-11-01T03:40:50.433 回答
2

我会考虑执行以下操作之一:


yourSequence |> Seq.windowed(2) |> Seq.forall(fun arr -> arr.[0] = arr.[1])

或者


let h = Seq.hd yourSequence
yourSequence |> Seq.forall((=) h)

尽可能使用库函数总是好的;)

于 2009-10-31T12:06:15.647 回答