I'm trying to create an abstraction for a lightweight data storage module using an F# signature file. Here is my signature file code, let's say it's called repository.fsi
namespace DataStorage
/// <summary>Lightweight Repository Abstraction</summary>
module Repository =
/// <summary> Insert data into the repository </summary>
val put: 'a -> unit
/// <summary> Fetch data from the repository </summary>
val fetch: 'a -> 'b
/// <summary> Remove data from the repository </summary>
val remove: 'a -> unit
Here is the corresponding implementation, let's call it repository.fs
namespace DataStorage
module Repository =
(* Put a document into a database collection *)
let put entity = ()
(* Select a document from a database collection *)
let fetch key = ("key",5)
(* Remove a document from a database collection *)
let remove entity = ()
In my visual studio project file I have the signature file (repository.fsi) above my implementation file (repository.fs). The put and remove functions are being parsed and verified correctly with no errors (in the implementation file) but the fetch function keeps giving me the red squiggly in visual studio with the following error message:
Module 'DataStorage.Repository' contains
val fetch: s:string -> string * int
but its signature specifies
val fetch<'a,'b> : 'a -> 'b
The respective type parameter counts differ
Can someone tell me what I'm doing wrong? Is my fetch function value defined wrong in my signature file? I'm just trying to create a generic function ('a -> 'b) in my signature file and have the implementation take one type as input and return a different type as output.
I am not very strong in F# yet but I think here you are using signature files in wrong way.
First. Here is how you can fix compilation errors:
Replace:
with:
and you won't get compilation errors. But this fix doesn't actually makes sense in many cases. For example if next works:
if you specify type explicity it will crash (in most cases):
The case is that generic implementation should operate with generic types. If I understod correctly from what are you trying to do you should use OOP and polymophism when signature files are used to hide implementation aspects. For example: