Q:

How do I declare a property of a record as an abstract function

I'm new to F# and functional programming and need some help. I come from c# so my mindset still gets in the way a bit.
I need to pass some options to a function and I'm using a record for this. One of the options is a continuation function unit -> Option<'a>. I can't figure out how to define the record type. Below is an example of what I've been trying.
type Func2<'a> = 'a -> 'a option

type ProcessOptions = {
        func1: int -> int option
        func2: Func2<int>   // This works...
        //func2: Func2<'a>  // ... but this is what I'm trying to achieve - so that I can pass any Func2<'a> using this record.
    }

let f1 a = 
    let r = Some a
    printfn "f1: %A" r |> ignore
    r

let f2 (a:'a) = 
    let r = Some a
    printfn "f2: %A" r |> ignore
    r

let f3 (processOptions:ProcessOptions) = 
    processOptions.func1(3) |> ignore
    processOptions.func2 789 |> ignore
    ()

let f4 (processOptions:ProcessOptions) = 
    processOptions.func1(4) |> ignore
    //processOptions.func2 "abc" |> ignore // as a result this does not work...
    ()

[<EntryPoint>]
let main argv = 

    f1(1) |> ignore
    f2 123 |> ignore
    f2 "abc" |> ignore

    let fo = {
        func1 = f1
        func2 = f2
    }
    f3 fo

    let fo1 = {
        func1 = f1
        func2 = f2
    }
    f4 fo1

    0 

A:

A member inside a record cannot be a generic function (that you can call with different types of arguments such as int or string). It will always have one fixed type.
A trick you can use is to define a simple interface with a generic method:
type Func = 
  abstract Invoke<'a> : 'a -> 'a option

Now your members in the record can be just of type Func (with no generic type arguments), but the Invoke method inside Func will be generic:
type ProcessOptions = 
      { func1: Func 
        func2: Func }

Creating Func values is a bit harder than writing ordinary functions, but you can use object expressions:
let f1 =
  { new Func2 with
      member x.Invoke(a) = 
        let r = Some a
        printfn "f1: %A" r |> ignore
        r }

And you can now pass around ProcessOptions and call the Invoke method with different types of arguments:
let f4 (processOptions:ProcessOptions) = 
    processOptions.func1.Invoke 4 |> ignore
    processOptions.func2.Invoke "abc" |> ignore

f4 { func1 = f1; func2 = f1 }

