Вы, конечно, можете, и вот как это выглядит:
let GetFNV1a32 (s: string) =
let offsetBasis = 2166136261un
// We only have to get the bytes once; now we have an entire array that we can perform monadic operations on
Encoding.UTF8.GetBytes s
// Array.fold's signature is ('State -> 't -> 'State) -> 'State -> 't[] -> 'State
// So here 'State is unativeint, and 't is byte, which is the current item of the byte[]. We can just transform it in one go to our output value, which becomes the value of acc the next time around.
|> Array.fold (fun acc byt -> MultiplyByPrimeFactor (XorWithHash (unativeint byt) acc))
offsetBasis // initial value
Вот быстрый тест, чтобы показать, что он работает, учитывая, что GetFNV1a32_old
является OP:
let xs =
[for str in ["TestString"; "Test String"; "foo BAR"; "BÄz qúåx"] do
let old, neww = GetFNV1a32_old str, GetFNV1a32 str
yield old, neww, (sprintf "does old = neww? %b" (old = neww))]
Что приводит к:
val xs : (unativeint * unativeint * string) list =
[(17683775798505137816un, 17683775798505137816un, "is old = neww? true");
(3444292159790811978un, 3444292159790811978un, "is old = neww? true");
(17137498406203898314un, 17137498406203898314un, "is old = neww? true");
(13890330577974722754un, 13890330577974722754un, "is old = neww? true")]