List 是否可以与F#中的分解序列匹配?

List 是否可以与F#中的分解序列匹配?,list,f#,pattern-matching,sequence,lazy-evaluation,List,F#,Pattern Matching,Sequence,Lazy Evaluation,我似乎记得F#的一个旧版本,它允许在匹配序列时进行结构分解,就像列表一样。有没有一种方法可以在保持序列惰性的同时使用列表语法?我希望避免给Seq.head和Seq.skip 1打很多电话 我希望有这样的东西: let decomposable (xs:seq<'a>) = match xs with | h :: t -> true | _ -> false seq{ 1..100 } |> decomposable let decomposab

我似乎记得F#的一个旧版本,它允许在匹配序列时进行结构分解,就像列表一样。有没有一种方法可以在保持序列惰性的同时使用列表语法?我希望避免给Seq.head和Seq.skip 1打很多电话

我希望有这样的东西:

let decomposable (xs:seq<'a>) =
   match xs with
   | h :: t -> true
   | _ -> false
seq{ 1..100 } |> decomposable

let decomposable(xs:seq如果您在PowerPack中使用LazyList类型,那么它具有称为LazyList.Nil和LazyList.Cons的活动模式,这两种模式非常适合于此

seq/IEnumerable类型并不特别适合于模式匹配;为此,我强烈推荐LazyList


Seq在活动模式下运行良好!除非我在这里做了一些可怕的事情

let (|SeqEmpty|SeqCons|) (xs: 'a seq) = //'
  if Seq.isEmpty xs then SeqEmpty
  else SeqCons(Seq.head xs, Seq.skip 1 xs)

// Stupid example usage
let a = [1; 2; 3]

let f = function
  | SeqEmpty -> 0
  | SeqCons(x, rest) -> x

let result = f a

我不知道如何将StackOverflow的代码高亮显示设置为F#模式,我认为这里使用的是OCaml,因此通用注释变得古怪…

记住,seq也有map reduce函数,所以您通常只能使用这些函数。在本例中,您的函数相当于“seq.isEmpty”。您可以尝试启动fsi,只需运行选项卡完成选项(输入“Seq.”并多次点击选项卡);它可能有你想要的。

对于需要单引号的情况,有一个技巧:在行末尾的注释中添加另一个单引号://“这是一个巧妙的技巧,但多个可靠的来源表明这不是一个好的模式,因为评估序列是O(n^2):没错,但发问者的例子不是递归的。这显然不适合在序列中递归,但如果你只是想在头部进行模式匹配或其他什么……请为(像我一样)不知道电源组是什么的人链接此处:LazyList现在是
FSharpx.Collections
let (|SeqEmpty|SeqCons|) (xs: 'a seq) = //'
  if Seq.isEmpty xs then SeqEmpty
  else SeqCons(Seq.head xs, Seq.skip 1 xs)

// Stupid example usage
let a = [1; 2; 3]

let f = function
  | SeqEmpty -> 0
  | SeqCons(x, rest) -> x

let result = f a