Bal*_*all 16 f# list sequence pattern-matching lazy-evaluation
我似乎记得F#的旧版本允许在匹配序列时进行结构分解,就像列表一样.有没有办法在保持序列延迟的同时使用列表语法?我希望避免大量调用Seq.head和Seq.skip 1.
我希望有类似的东西:
let decomposable (xs:seq<'a>) =
match xs with
| h :: t -> true
| _ -> false
seq{ 1..100 } |> decomposable
Run Code Online (Sandbox Code Playgroud)
但这仅处理列表并在使用序列时给出类型错误.当使用List.of_seq时,它似乎会评估序列中的所有元素,即使它是无限的.
Bri*_*ian 23
如果你在PowerPack中使用LazyList类型,它有一个名为LazyList.Nil和LazyList.Cons的活动模式.
seq/IEnumerable类型并不特别适合模式匹配; 我强烈推荐LazyList.(另请参阅为什么使用序列比使用此示例中的列表慢得多.)
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我不知道如何将StackOverflow的代码突出显示为F#模式,我认为它在这里使用OCaml所以通用注释很古怪......