f-sharp
  1. f-sharp-generics

F# Generics

Generics refer to the mechanism to define type parameters in functions, classes, and interfaces at compile time. It helps in writing reusable code that can work with different data types without the need for code duplication.

Syntax

F# supports generic type parameters in the following ways:

  1. Defining a generic function:
let functionName<'T> (parameters : 'T) = 
    // Function body
  1. Defining a generic class:
type className<'T1, 'T2> (parameters : 'T1, 'T2) = 
    // Class body
  1. Defining a generic interface:
type interfaceName<'T> = 
    // Interface body

Example

// Defining a generic function to get the largest element from any array
let inline largestElement (arr: _ []) = 
    if arr.Length = 0 then None
    else
        let mutable largest = arr.[0]
        for i in 1 .. arr.Length-1 do
            if arr.[i] > largest then largest <- arr.[i]
        Some(largest)
    
let intArr = [| 1; 2; 3; 4; 5 |]
let floatArr = [| 1.0; 2.5; 3.7; 4.1; 5.8 |]
let stringArr = [| "apple"; "banana"; "orange"; "pear" |]

printfn "Largest element in intArr: %A" (largestElement intArr)
printfn "Largest element in floatArr: %A" (largestElement floatArr)
printfn "Largest element in stringArr: %A" (largestElement stringArr)

Output

Largest element in intArr: Some(5)
Largest element in floatArr: Some(5.8)
Largest element in stringArr: Some("pear")

Explanation

In the above example, we have defined a generic function named largestElement that can take an array of any data type. We have used the inline keyword to make the function a generic function.

The function takes an array of any data type as input and returns the largest element in the array. We have used the if statement to check if the length of the array is zero or not. If the length is zero, the function returns None. Otherwise, we initialize a mutable variable named largest with the first element of the array. Then, we iterate through the array and compare each element with the largest variable. If the current element is greater than the largest variable, we update the largest variable. Finally, the function returns the largest variable wrapped in a Some case.

We have tested the generic function with three different types of arrays: intArr, floatArr, and stringArr.

Use

Generics are widely used in F# for the following reasons:

  • They help in writing reusable code that can work with different data types without the need for code duplication.
  • They provide better type safety by catching type errors at compile time.
  • They improve performance by reducing the overhead of runtime type casting and boxing/unboxing.

Generics in F# can be used to define generic functions, classes, and interfaces.

Important Points

  • F# supports generic type parameters for functions, classes, and interfaces.
  • Generic type parameters are defined using the 'T syntax.
  • The inline keyword is used to make a function a generic function.
  • Generics help in writing reusable code and improving performance.
  • Generics provide better type safety by catching type errors at compile time.

Summary

In this tutorial, we have learned about generics in F#. Generics provide a powerful mechanism for writing reusable code that can work with different data types. We have seen how to define and use generic functions, classes, and interfaces in F#. We have also learned the benefits of using generics in F#.

Published on: