Confused about subtyping functions

I take a course in programming languages, and the answer to the question "when a function is a subtype of another function" is very intuitive for me.

To clarify: suppose we have the following relation of type:

bool<int<real

Why is a function (real->bool)a subtype (int->bool)? Shouldn't it be the other way around?

I would expect the criteria for sub-printing functions: f1 is a subtype of f2 if f2 can take any argument that f1 can take, and f1 returns only the values ​​returned by f2. Obviously, the values ​​of f1 can take, but f2 cannot.

+5
source share
2 answers

Here is the rule for the subtype of the function:

, -.

Co-variant == "A" B " .

Contra-variant == ( " " ) .

, :

f1:  int  -> bool
f2:  bool -> bool

, f2 f1. ? (1) , , "bool - int" -. ints bools. (2) , , .

( , ):

: " , , , , ". co-variant : " , , , / , , "

, , :

f1:  {x,y,z} -> {x,y}
f2:  {x,y}   -> {x,y,z}

, , f2 f1 ( ). ( < " " ), f2 < f1, {x, y, z} {x, y}? - . {x, y, z} {x, y}. .. {x, y, z} "" {x, y}, , z.

, f2 < f1, {x, y} > {x, y, z}? . (. ).

- , f2 < f1, , . (psuedo-code):

   F1 = f1;
   F2 = f2;
   {a,b}   = F1({1,2,3});  // call F1 with a {x,y,z} struct of {1,2,3};  This works.
   {a,b,c} = F2({1,2});    // call F2 with a {x,y} struct of {1,2}.  This also works.

   // Now take F2, but treat it like an F1.  (Which we should be able to do, 
   // right?  Because F2 is a subtype of F1).  Now pass it in the argument type 
   // F1 expects.  Does our assignment still work?  It does.
   {a,b} = ((F1) F2)({1,2,3});
+5

, , , , , / .


:

function subtyping rule

, , true.

, T1 S1. , T2 S2.

, ? Aaron Fi, ( " " ):

, S1 → S2, , T1 → T2 , , , (T1 <: S1), , , (S2 <: T2).

, , , . .

, :

  • S1 := {x, y}
  • T1 := {x, y, z}
  • T2 := {a}
  • S2 := {a, b}

:

  • f1 S1 → S2 ⟹ {x, y} → {a, b}
  • f2 T1 → T2 ⟹ {x, y, z} → {a}

, type(f1) <: type(f2). , , , , .

map( f2 : {x, y, z} → {a}, L : [ {x, y, z} ] ) : [ {a} ]

f2 f1, :

map( f1 : {x, y} → {a, b}, L : [ {x, y, z} ] ) : [ {a, b} ]

, :

  • , f1 , z .
  • , map , b .

:

{x, y} → {a, b} ⟹ {x, y, z} → {a} ✔

:

  • f1 T1 → S2 ⟹ {x, y, z} → {a, b}
  • f2 S1 → T2 ⟹ {x, y} → {a}

, type(f1) <: type(f2)

map( f2 : {x, y} → {a}, L : [ {x, y} ] ) : [ {a} ]

f2 f1, :

map( f1 : {x, y, z} → {a, b}, L : [ {x, y} ] ) : [ {a, b} ]

, f1 z, - L. ⚡

:

  • f1 S1 → T2 ⟹ {x, y} → {a}
  • f2 T1 → S2 ⟹ {x, y, z} → {a, b}

, type(f1) <: type(f2)

map( f2 : {x, y, z} → {a, b}, L : [ {x, y, z} ] ) : [ {a, b} ]

f2 f1, :

map( f1 : {x, y} → {a}, L : [ {x, y, z} ] ) : [ {a} ]

z f1, , map, b, . ⚡

, .

, , , . , , .

+2

All Articles