简体   繁体   中英

Write f# Function that takes parameterized constructor

I want to write a function that creates an object from a data stream, eg

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?

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

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM