F # casting an object to an interface

I have a class called Panel (think glass glass) that implements IPane:

type IPane =
    abstract PaneNumber : int with get, set
    abstract Thickness : float<m> with get, set
    abstract ComponentNumber : int with get, set
    abstract Spectra : IGlassDataValues with get, set
    ...

type Pane(paneNumber, componentNumber, spectra, ...) =
    let mutable p = paneNumber
    let mutable n = componentNumber
    let mutable s = spectra
    ...

    interface IPane with
        member this.PaneNumber
            with get() = p
            and set(value) = p <- value
        member this.ComponentNumber
            with get() = n
            and set(value) = n <- value
        member this.Spectra
            with get() = s
            and set(value) = s <- value
            ...

I create a list of panels (list of panels):

let p = [ p1; p2 ]

however, I need to pass this to the IPane list, as this is the type of parameter in another function. The following code throws an error:

let p = [ p1; p2 ] :> IPane list
'Type constraint mismatch. The type
  Pane list
is not compatible with type
  IPane list
The type 'IPane' does not match the type 'Pane'

This is confusing as the panel implements IPane. Simply moving the Panel list object as a parameter to the desired function also causes an error.

How to make a list of panels a list of IPane?

+4
source share
3 answers

F # does not allow you to inherit the way you want.

Best used:

[p1 ;p2] |> List.map (fun x -> x:> IPane)

Alternatively, you can change your function to use something like this

let f (t:#IPane list) = ()

f [p1;p2], # , , IPane, .

+5

:

let p = [p1; p2] : IPane list
// or equivalently
let p : IPane list = [p1; p2]

, [p1; p2] - , , , Pane list, IPane list, " t, F # : Pane IPane, Pane list IPane list.

, , , [p1; p2], , IPane list, ; p1 p2 IPane.

+2

The solution was simpler than I thought.

I defined p1 and p2 as:

let p1 = new Pane(1, 2, blah, blah)
let p2 = new Pane(2, 2, blah, blah)

However, if I show them as IPanes, everything works:

let p1 = new Pane(1, 2, blah, blah) :> IPane
let p2 = new Pane(2, 2, blah, blah) :> IPane

John Palmer's decision above is probably more rigorous since the original panel objects are supported as concrete types.

0
source

Source: https://habr.com/ru/post/1543370/


All Articles