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