I have the following interface defined in a C# library
public interface IMatch
{
string CompetitionId { get; }
int MatchNumber { get; }
MatchType Type { get; }
SeriesType SeriesType { get; }
bool Finished { get; }
}
I've then created a type in my F# library that implements the interface like this
type Match(
competitionId: string,
finished: bool,
matchNumber: int,
seriesType: SeriesType,
matchType: MatchType) =
interface IMatch with
member this.Finished with get() = finished
member this.MatchNumber with get() = matchNumber
member this.SeriesType with get() = seriesType
member this.Type with get() = matchType
member this.CompetitionId with get() = competitionId
Now, I read this article and I saw the WithUpdatedEmail
method on the Person type:
type Person = {
FirstName: string
LastName: string
Email: string
}
with member this.WithUpdatedEmail email = { this with Email = email }
When calling that method, it will return a new Person instance with the updated email. Is it possible to add a method like that on my Match
type? I've tried the following but I can't get it to compile( The record label Finished
is not defined ), Im completely new to F# so please bear with me if this isn't possible... :)
type Match(
competitionId: string,
finished: bool,
matchNumber: int,
seriesType: SeriesType,
matchType: MatchType) =
interface IMatch with
member this.Finished with get() = finished
member this.MatchNumber with get() = matchNumber
member this.SeriesType with get() = seriesType
member this.Type with get() = matchType
member this.CompetitionId with get() = competitionId
with member this.Finished finished = { this with Finished = finished}
Copy and update record expressions — the one, which allows you to write { rec with prop = val }
— is a convenient shortcut for creation of new record with a few changes from existing record instance.
I may be wrong, for sure, but this syntax is allowed for record types only, while you've declared a Match
class with custom constructor, which is not a record.
So you may want to use a record instead.
type Match =
{ CompetitionId: string
Finished: bool
MatchNumber: int
SeriesType: SeriesType
MatchType: MatchType }
interface IMatch with
member this.Finished with get() = this.Finished
member this.MatchNumber with get() = this.MatchNumber
member this.SeriesType with get() = this.SeriesType
member this.Type with get() = this.MatchType
member this.CompetitionId with get() = this.CompetitionId
member this.WithFinished finished = { this with Finished = finished}
Member WithFinished
is quite useless from F# point of view as you could always use with
expression directly.
let m = { CompetitionID = "1"; Finished = false; ...}
let m2 = { m with CompetitionId = "42" }
But it may be suitable for C# interoperability.
If you want to leave Match
as a class, then you should implement WithFinished
manually providing all the arguments.
member this.WithFinished finished =
Match(competitionId, finished, matchNumber, seriesType, matchType)
But I doubt that it will be useful, because interfaces are always implemented as explicit in F#, it means you won't be able to access your Match
class properties without a cast to IMatch
from F# side.
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.