代码之家  ›  专栏  ›  技术社区  ›  Ball

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

  •  16
  • Ball  · 技术社区  · 15 年前

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

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

    3 回复  |  直到 15 年前
        1
  •  27
  •   Community CDub    8 年前

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

    seq/IEnumerable类型并不特别适合于模式匹配;我强烈推荐LazyList。(另见 Why is using a sequence so much slower than using a list in this example .)

    let s = seq { 1..100 }
    let ll = LazyList.ofSeq s
    match ll with
    | LazyList.Nil -> printfn "empty"
    | LazyList.Cons(h,t) -> printfn "head: %d" h
    
        2
  •  11
  •   sdgfsdh    3 年前

    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
    
        3
  •  1
  •   gatoatigrado    14 年前

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