2009-11-17 6 views
15

Me parece recordar una versión anterior de F # que permite la descomposición estructural cuando se combinan secuencias al igual que las listas. ¿Hay alguna manera de usar la sintaxis de la lista mientras se mantiene la secuencia floja? Tengo la esperanza de evitar una gran cantidad de llamadas a Seq.head y Seq.skip 1.¿Es posible combinar con secuencias descompuestas en F #?

que estoy esperando algo como:

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

Pero esto sólo se ocupa de las listas y da un error de tipo cuando usando secuencias. Al usar List.of_seq, parece evaluar todos los elementos en la secuencia, incluso si es infinito.

Respuesta

21

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 es particularmente compatible con la coincidencia de patrones; Recomiendo LazyList para esto. (Consulte también 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 
+5

enlace aquí para cualquier persona que (como yo) no sabía lo que es el paquete de alimentación: http://fsharppowerpack.codeplex.com/ – gatoatigrado

7

Seq funciona bien en los patrones activos! A menos que estoy 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 conseguir el código de Stackoverflow destacando en modo F #, creo que es el uso de OCaml aquí, así que la anotación genérica va loco ...

+3

Un truco para casos en los que desea una sola comilla simple: Agregar otra sola- citar en un comentario al final de la línea: // ' – harms

+7

Es un truco ingenioso, pero más de una fuente confiable indica que no es un buen patrón ya que la evaluación de la secuencia es O (n^2): http: // stackoverflow .com/questions/1306140/f-why-is-using-a-sequence-so-much-slower-than-use-a-list-in-this-example/1306267 # 1306267 – Juliet

+1

Cierto, pero el ejemplo del que pregunta es no recursivo Obviamente, esto no es bueno para volver a generar la secuencia, pero si solo quieres hacer coincidir patrones en la cabeza o algo ... –

0

Recuerde que seq también tiene funciones para reducir mapas, por lo que a menudo puede salirse con la suya solo. En el ejemplo, su función es equivalente a "Seq.isEmpty". Puede tratar de iniciar fsi y simplemente ejecutar las opciones de finalización de pestañas (ingrese "Seq." Y pulse la pestaña mucho); podría tener lo que quieres.

Cuestiones relacionadas