F# 表达式以测试序列中的所有项是否相同

F# 表达式以测试序列中的所有项是否相同,f#,pattern-matching,F#,Pattern Matching,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;…]也应该

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;…]也应该返回列表,但我不知道如何匹配最后一个模式。这可能吗?还是有更好的方法可以使用?我还没有找到任何关于重复模式的信息。

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

let allSame L =
    match L with
    | [] | [_] -> L
    | h::t when t |> List.forall ((=) h) -> L
    | _ -> failwith "unpossible!" //handle the failing match here
另外,你说的是一个序列,但你的匹配表明你正在处理一个列表。序列的对应代码如下所示

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

请注意,这个函数的性能可能比基于列表的函数的性能差。

< P>我会考虑做以下一个:


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


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

这里是一个使用多案例活动模式的解决方案

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"
let(| SingleOrEmpty | AllIdentical | note |)(lst:'a list)=
如果lst.长度小于2,则
单身或空虚
elif List.forall(fun elem->elem=lst[0])lst然后
牙科的
其他的
也不
让等位体lst:'列表=
匹配lst与
|单一或空|所有身份->lst
|都不->失败,并带有“不合适的列表”

@cfern,你说得对。我确实需要小心我使用的术语。我倾向于使用“List”和“Sequence”,就好像它们是同义词一样——而在F#中,它们绝对不是同义词。我正在处理一份清单。
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"