Jamie Dixon
Jamie Dixon

Reputation: 4282

Need help translating interfaces with generics into F# from C#

I have this C# code

public interface IDinnerRepository : IRepository<Dinner>
{
    IQueryable<Dinner> FindByLocation(float latitude, float longitude);
    IQueryable<Dinner> FindUpcomingDinners();
    IQueryable<Dinner> FindDinnersByText(string q);
    void DeleteRsvp(RSVP rsvp);
}

and

public interface IRepository<T>
{
    IQueryable<T> All { get; }
    IQueryable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties);
    T Find(int id);
    void InsertOrUpdate(T dinner);
    void Delete(int id);
    void SubmitChanges();
}

that I want to translate into F#. How do I make an interface of generics? The MSDN examples of F# interfaces don't really have an equiv. as far as I could tell.

Upvotes: 2

Views: 77

Answers (2)

Tomas Petricek
Tomas Petricek

Reputation: 243041

There are actually two ways to define generic interfaces, but pretty much all F# code around uses the style that you mentioned in your existing answer. The other option is used only for some standard F# types like 'T option and 'T list:

type IRepository<'T> = // The standard way of doing things
type 'T IRepository =  // Used rarely for some standard F# types

As for the other member types that occur in your sample interfaces, some of them are actually a bit interesting, so here is a more complete translation (just for the future reference!)

// We inherit from this type later, so I moved it to an earlier location in the file
type IRepository<'T> =
  // Read-only properties are easier to define in F#
  abstract All : IQueryable<'T>
  // Annotating parameter with the 'params' attribute and also specifying param name
  abstract AllIncluding 
    : [<ParamArray>] includeProperties:Expression<Func<'T, obj>>[] -> IQueryable<'T>


type IDinnerRepository =
  // Inherit from another interface
  inherit IRepository<Dinner>

  // And add a bunch of other members (here I did not specify parameter names)
  abstract FindUpcomingDinners : unit -> IQueryable<Dinner>
  abstract FindDinnersByText : string -> IQueryable<Dinner>

Upvotes: 5

Jamie Dixon
Jamie Dixon

Reputation: 4282

OK, I should have goolged "F# Interfaces with generics" first.

type public IRepository<'T> =

Will work...

Upvotes: 2

Related Questions