Basics 11 - Generics (Basics)

Time to discuss generics.

What is Generics

Consider this function:

let apply f a = f a

A function:

  1. Named apply

  2. Takes two parameters:

    1. f, a function, which takes one parameter

    2. a, passed to f

  3. Returns whatever is returned by the call f a

If you inspect the function you see something like this:

A generic apply function.

If you pay attention to the types:

  1. f is of type 'a -> 'b

  2. a is of type 'a

  3. The return type of apply is 'b

  4. Type 'a and 'b that you see here are generic types

Generenics, as the name implies, means something is in a general form and shape, as opposed to being specific.

let apply (f: int -> string) (a: int) : string = f a

This version of apply has a very specific implementation. f is int -> string, a is int, and the return type is string. This version of apply does the same thing as the previous version, however, isn't generalized.

Generics allow the implementation of generalized functions and types.

Generics with Discriminated Unions and Records

type Either<'l, 'r> =
    | Left of 'l
    | Right of 'r

let a = Left 1 // 'l = int
let b = Left "1" // 'l = string

let c = Right 1 // 'r = int
let d = Right "1" // 'r = int

The above shown is an example of a discriminated union type. There are two cases. Left and Right. Both cases are based on generic types. Left is of type 'l, and Right is of type 'r.

type Student<'t> =
    { Name: string
      RollNo: 't }

let jack = { Name = "Jack"; RollNo = 12345 } // 't = int
let jill = { Name = "Jill"; RollNo = "#ABCDE1" } // 't = string

The above shown is an example of a record type. The Student type offers flexibility for the type of RollNo.

Generics with Functions

Here are some examples:

// f: ('a -> 'b) -> a: 'a -> 'b
let apply f a = f a

// a: 'a -> b: 'a -> bool when 'a: comparison
// ignore when 'a: comparison for the moment
// will discuss later
let isGreater a b = a > b

// a: 'a -> b: 'b -> 'a * 'b
// 2 value to tuple conversion
let toTuple a b = (a, b)

// 'a * 'b -> 'a
// First value from tuple
let firstOfTuple tup =
    let (a, _) = tup
    a

If you have reached so far, congratulations.

Keep reading!