2015-01-21 19 views
5

Ho una funzione per calcolare la somma cumulata di una sequenza.Zero generico per funzione generica

let cumsum<'T> = Seq.scan (+) 0 >> Seq.skip 1 >> Seq.toArray 

Anche se sembra generico, l'intero 0 rende non generico, e pertanto non può chiamare la funzione con una sequenza di galleggianti.

C'è uno zero generico che può sostituire il mio 0 con hardcoded, o forse un modo diverso di rendere generica la funzione.

risposta

9

È possibile utilizzare il GenericZero primitiva, ma è necessario per rendere la vostra funzione inline e renderlo esplicitamente una funzione (in questo momento la funzione è scritto in point-free style) dal momento che in valori di principio non può essere fatta in linea.

let inline cumsum s = 
    s |> Seq.scan (+) LanguagePrimitives.GenericZero |> Seq.skip 1 |> Seq.toArray 

nota che, eliminando il parametro Type 'T vincoli membro statiche sono dedotte automaticamente dal compilatore:

val inline cumsum : 
    s:seq< ^a> -> ^b [] 
    when (^b or ^a) : (static member (+) : ^b * ^a -> ^b) and 
      ^b : (static member get_Zero : -> ^b) 
2
LanguagePrimitives.GenericZero 

:)

+2

noti che 'cumsum' deve essere fatta una funzione ancorato piuttosto che un valore per ha l'effetto desiderato, ovvero 'lascia inline cumsum x = x |> Seq.scan (+) LanguagePrimitives.GenericZero |> Seq.skip 1 |> Seq.toArray'. – ildjarn

+0

Non ho nemmeno bisogno di controllare reddit! :) – kasperhj

+0

@ildjarn Perché è quello? – kasperhj

Problemi correlati