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.

+3


source to share


3 answers


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

      

+3


source


@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

      

+7


source


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

      

+2


source







All Articles