Question

In F# I have the following bit of code

[<Literal>]
let fname=fstFile.FullName.ToString()
type genomeFile = CsvProvider<fname>

Where fstFile is an instance of the FileInfo class. However, this fails with:

This is not a valid constant expression or custom attribute value

And I can't seem to create the type without an actual hard coded string. Does anyone know how to fix this?

Was it helpful?

Solution

The parameter to the CSV type provider needs to be a constant, so that the types can be generated at compile-time (without actually evaluating the program. However, you can load a different file with the same schema at runtime.

So, the best way to handle this is to copy one of your actual inputs to some well-known location (e.g. sample.csv in the same directory as your script) and then use the actual path at runtime:

// Generate type based on a statically known sample file
type GenomeFile = CsvProvider<"sample.csv">

// Load the data from the actual input at runtime
let actualData = GenomeFile.Load(fstFile.FullName.ToString())

OTHER TIPS

However, if you reference a literal in an already compiled DLL it will work. So, for example if you split your example into two projects,

e.g. create a new project with TypeProviderArgs.fs ==> TypeProviderArgs.dll

module TypeProviderArgs
[<Literal>]
let fname=fstFile.FullName.ToString()

Then reference TypeProviderArgs.dll in your program and it should work

type genomeFile = CsvProvider<TypeProviderArgs.fname>

This is kind of horrible if you have to create a library just for this purpose, but if you are in a larger project that already has libraries it's not so bad.

The problem is that [<Literal>] can only be applied to things known at compile time (e.g. "Hello").

The result of fstFile.FullName.ToString() is only known at run-time.

This sort of approach won't work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top