evolvedmicrobe
evolvedmicrobe

Reputation: 2722

Write f# Function that takes parameterized constructor

I want to write a function that creates an object from a data stream, e.g.

let nxL<'T  when 'T : (new : unit -> 'T)> (sr:StreamReader) = 
    let line = sr.ReadLine()
    if line <> null then 
        Some(new 'T(line))
    else
        None

However, this doesn't work as it fails with:

Calls to object constructors on typed parameters cannot be given arguments.

Since a constructor is a function and F# is a functional language this makes no sense to me. Does anyone know how to create a function that takes a type as an argument and returns new instances?

Upvotes: 1

Views: 129

Answers (2)

Daniel
Daniel

Reputation: 47904

Although passing a function, as @scrwtp suggested, is a good aproach, what you want is possible:

let inline nxL (sr:StreamReader) = 
    let line = sr.ReadLine()
    if line <> null then 
        Some(^a : (new : string -> ^a) line)
    else
        None

Upvotes: 2

scrwtp
scrwtp

Reputation: 13577

You could create an object given a type using Activator.CreateInstance, but I don't feel it's strictly necessary from the code snippet you posted. Wouldn't passing a regular function that takes a string and returns an object of the desired type work for you? Sort of a factory function, if you care. Like this:

let nxL<'T> (cons: string -> 'T) (sr:StreamReader) : 'T option = 
    let line = sr.ReadLine()
    if line <> null then 
        Some (cons line)
    else
        None

What's more, you could actually drop all the type annotations on it apart from StreamReader, and it will be inferred to be generic (leaving them on so it's clear what goes on in the snippet).

Upvotes: 0

Related Questions