F # nested generic types not compatible with an implemented type

Background:

Given the following two declarations in the F # program:

  • type Aimplements an interfaceWrapped<int>
  • type Bimplements an interfaceWrapped<A>

We say that the type is Acompatible with Wrapped<int>and the type is Bcompatible with Wrapped<A>- compatible, as I understand it, which means that it Acan be passed to a function that requires Wrapped<int>.

Problem:

From my programming experience, I would expect the following to also be true, given the two statements above:

  • type Bmust be compatible with typeWrapped<Wrapped<int>>

because it Bhas Aboth a type parameter where it Wrapped<int>should go, and Aboth are Wrapped<int>compatible.

This is not true. The following implementation:

type Wrapper<'a> = abstract member Value : 'a

type A =
    | A of int

    interface Wrapper<int> with member this.Value = (let (A num) = this in num)

type B =
    | B of A

    interface Wrapper<A> with member this.Value = (let (B a) = this in a)


let f (x:Wrapper<Wrapper<int>>) =
    x.Value.Value

let testValue = f (B (A 1))

has a compilation error on B (A 1)indicating

B Wrapper<Wrapper<int>>

:

, - , ? F # " ", , ?


:

type B =
    | B of A

    interface Wrapper<Wrapper<int>> with member this.Value = (let (B a) = this in a :> Wrapper<int>)

, . : " , - Wrapper<A>? ( - Wrapper<A>)

+4
1

, , - .

, , ( , ). IEnumerable<string> :?> IEnumerable<object> string :?> object.

.NET. #:

interface Wrapper<out T> { }
class A : Wrapper<int> { }
class B : Wrapper<A> { }          

var b = new B();
Action<Wrapper<Wrapper<int>>> unwrap = _ => { };
unwrap(b); //compiles

F # , . , .

F # . F # seq, IEnumerable<out T>.

let s = [1..10] 
let r =  s |> Seq.map(fun _ -> s)

let print1 (v: seq<seq<int>>) = printfn "%A" v
let print2 (v: seq<#seq<_>>) = printfn "%A" v

print1 r //does not compile
print2 r //compiles

, , , . # F #.

mausch/VariantInterfaces, / , , type , post-build.

+5

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


All Articles