21

F# の古いバージョンでは、リストと同じようにシーケンスを照合するときに構造分解が可能だったことを覚えているようです。シーケンスを怠惰に保ちながらリスト構文を使用する方法はありますか? Seq.head と Seq.skip 1 への多くの呼び出しを避けたいと思っています。

私は次のようなことを望んでいます:

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

ただし、これはリストのみを処理し、シーケンスを使用すると型エラーが発生します。List.of_seq を使用すると、無限であっても、シーケンス内のすべての要素を評価するようです。

4

3 に答える 3

27

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
于 2009-11-17T15:29:33.373 に答える
11

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
于 2009-11-18T16:40:58.050 に答える
1

seq には map reduce 関数もあるということを覚えておいてください。この例では、関数は「Seq.isEmpty」と同等です。fsi を起動して、タブ補完オプションを実行しようとするかもしれません (「Seq.」と入力してタブを何度も押します)。欲しいものがあるかもしれません。

于 2010-06-11T19:48:30.900 に答える