2015-01-21 13 views
5

Mam funkcję obliczania skumulowanej sumy sekwencji.Generyczne zero dla funkcji ogólnej

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

Choć wygląda rodzajowa, całkowitą 0 sprawia, że ​​non-generic, a więc nie mogę wywołać funkcję z sekwencją pływaków.

Czy istnieje ogólne zero, które może zastąpić moje zakodowane na stałe 0, lub może inny sposób na uczynienie tej funkcji ogólną.

Odpowiedz

9

Można użyć GenericZero prymitywny, ale trzeba dokonać funkcji inline i sprawiają, że wyraźnie funkcją (teraz czynność opisana w point-free style), ponieważ w wartościach zasada ta nie może być wykonana inline.

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

Zauważmy, że usuwając parametr typu 'T statyczne ograniczenia członkowskie są wywnioskować automatycznie przez kompilator:

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

Zauważ, że 'cumsum' muszą być wykonane funkcję inline zamiast wartości w celu mieć zamierzony efekt, tj. "let inline cumsum x = x |> Seq.scan (+) LanguagePrimitives.GenericZero |> Seq.skip 1 |> Seq.toArray'. – ildjarn

+0

Nawet nie musiałem sprawdzać reddita! :) – kasperhj

+0

@ildjarn Dlaczego tak jest? – kasperhj

Powiązane problemy