list - name - ¿Es posible hacer coincidir con secuencias descompuestas en F#?
meta tags list (3)
Parece que recuerdo una versión anterior de F # que permite la descomposición estructural al hacer coincidir secuencias como listas. ¿Hay alguna forma de usar la sintaxis de la lista mientras se mantiene la secuencia perezosa? Espero evitar muchas llamadas a Seq.head y Seq.skip 1.
Estoy esperando algo como:
let decomposable (xs:seq<''a>) =
match xs with
| h :: t -> true
| _ -> false
seq{ 1..100 } |> decomposable
Pero esto solo maneja listas y da un error de tipo cuando se usan secuencias. Cuando se usa List.of_seq, parece evaluar todos los elementos en la secuencia, incluso si es infinito.
Recuerde que seq también tiene funciones de reducción de mapas, por lo que a menudo podría salirse con la suya solo con esas. En el ejemplo, su función es equivalente a "Seq.isEmpty". Puede intentar iniciar fsi y simplemente ejecutar las opciones de finalización de la pestaña (ingrese "Seq." Y presione la pestaña mucho); podría tener lo que quieras
Seq funciona bien en patrones activos! A menos que esté haciendo algo horrible aquí ...
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
No sé cómo hacer que el código de se destaque en el modo F #, creo que está usando OCaml aquí, por lo que la anotación genérica se vuelve loca ...
Si usa el tipo LazyList en el PowerPack, tiene patrones activos llamados LazyList.Nil y LazyList.Cons que son excelentes para esto.
El tipo seq / IEnumerable no está particularmente sujeto a la coincidencia de patrones; Recomiendo encarecidamente a LazyList para esto. (Vea también Por qué está usando una secuencia mucho más lenta que usando una lista en este ejemplo ).
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