Maximum / minimum value of a type in F #
Unchecked.defaultof<'T>
generates a default value for any type. Is there such a general function to generate the maximum / minimum value for any type where a maximum / minimum value type makes sense?
EDIT
To answer John Palmer's question about where I think it would be useful: I want to create a "mutable" version of the function below:
let InternalArrDiffMax (s : 'T []) (diff : 'T -> 'T -> 'C) =
s
|> Array.mapi (fun i e ->
[| for j in i + 1 .. s.Length - 1 -> diff e s.[j] |]
|> Array.maxBy (fun n -> n))
|> Array.maxBy (fun e -> e)
Since I cannot declare a mutable variable without assigning a value to it, I don't think there is any other way to do this than:
let InternalArrDiffMax (s : 'T []) (diffFun : 'T -> 'T -> 'C) =
let mutable max : 'C = // Generic max of 'C if it makes sense
for i in 0 .. s.Length - 1 do
for j in i + 1 .. s.Length - 1 do
let diff = diffFun s.[i] s.[j]
if (i = 0 && j = 1) || max < diff then
max <- diff
max
This is why I think I need a total max.
source to share
If you must continue this route, there will always be Reflection. However, I would suggest using it MaxValue
as an out-of-band or special value.
let inline tryGetMaxValue< ^a> () =
match typeof< ^a>.GetField("MaxValue") with
| null -> None
| fieldInfo -> fieldInfo.GetValue() |> unbox< ^a> |> Some
let maxvi = tryGetMaxValue<int>() // val maxvi : int option = Some 2147483647
let maxvf : float option = tryGetMaxValue() // val maxvf : float option = Some 1.797693135e+308
let maxvs : string option = tryGetMaxValue() // val maxvs : string option = None
source to share
@kaefer's answer gives you a nice way to get max / min values ββwhere applicable, but for your specific use case, I suggest changing the variable instead 'C option
and initializing it to None
. No magic numbers required.
let InternalArrDiffMax (s : 'T []) (diffFun : 'T -> 'T -> 'C) =
let mutable max : 'C option = None
for i in 0 .. s.Length - 1 do
for j in i + 1 .. s.Length - 1 do
let diff = diffFun s.[i] s.[j]
match max with
| None ->
max <- Some diff
| Some v when v < diff ->
max <- Some diff
| _ -> ()
max
source to share
Reflection-free approach
let maxOfT (x:'t) : 't =
match typedefof<'t> with
| u when u=typedefof<Int16> -> Int16.MaxValue :> obj
| u when u=typedefof<Int32> -> Int32.MaxValue :> obj
// ... repeat for each type
| _ -> failwith "unrecognised"
:?> 't
let minOfT (x:'t) : 't =
match typedefof<'t> with
| u when u=typedefof<Int16> -> Int16.MinValue :> obj
| u when u=typedefof<Int32> -> Int32.MinValue :> obj
// ... repeat for each type
| _ -> failwith "unrecognised"
:?> 't
source to share