Skip to content

Instantly share code, notes, and snippets.

@Savelenko
Created September 25, 2023 10:04
Show Gist options
  • Select an option

  • Save Savelenko/8ff918ffdaa06760fd3fd79e7461e467 to your computer and use it in GitHub Desktop.

Select an option

Save Savelenko/8ff918ffdaa06760fd3fd79e7461e467 to your computer and use it in GitHub Desktop.

Revisions

  1. Savelenko created this gist Sep 25, 2023.
    39 changes: 39 additions & 0 deletions RankNExample.fs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,39 @@

    // A polymorphic function which works for values of *any* type.
    let hello (a : 't) : string =
    // Just ignore the argument
    "Hello"

    // We can use it any context, on any input: it is polymorphic after all.
    let result =
    let a = hello 1
    let b = hello "string"
    a + b

    // We are doing FP here, so replacing a constant with a variable is a standard
    // technique, for example for constant `1` above. By doing so `result` becomes
    // a function:

    let result2 i =
    let a = hello i // Constant `1` became variable `i` in this expression
    let b = hello "string"
    a + b

    // So far so good. But functions are also values, so instead of replacing `1` with
    // a variable, let's replace constant `hello` with a variable. By doing so `result`
    // becomes a higher-order function:

    let result3 f =
    let a = f 1 // Constant `hello` became variable `f` in this and other expressions
    let b = f "string" // Type error here: "This expression was expected to be int"
    a + b

    // Whoops! We applied seemingly the same transformation (replace a constant with a
    // variable), but it does not work! It means F# is not uniform in handling values
    // as functions, at least not in all cases. Most people are surprised by this example,
    // followed by a slight disappointment and rightfully so.
    //
    // This is because F# type system does not support higher-ranked types (HRT, not to
    // be confused with HKT). However, it is well-known that this can be "fixed" by using
    // object methods. HRT are supported in some other FP languages natively for functions,
    // without methods and objects.