Можно ли сопоставить с разложенными последовательностями в F #? - PullRequest
16 голосов
/ 17 ноября 2009

Кажется, я помню более старую версию 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 кажется, что он оценивает все элементы в последовательности, даже если она бесконечна.

Ответы [ 3 ]

22 голосов
/ 17 ноября 2009

Если вы используете тип LazyList в PowerPack, у него есть активные шаблоны с именами 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
8 голосов
/ 18 ноября 2009

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, поэтому общая аннотация становится дурацкой ...

0 голосов
/ 11 июня 2010

Помните, что в seq также есть функции сокращения карт, так что вы часто можете обходиться без них. В этом примере ваша функция эквивалентна «Seq.isEmpty». Вы можете попытаться запустить fsi и просто запустить опции завершения вкладки (введите «Seq.» И сильно нажмите вкладку); это может иметь то, что вы хотите.

...