Deklaráció

7.1. Kérdés.
A következő probléma merült fel a nagyházimmal. Az elkészült program mosml-lel működik:

> val felhok = fn :
  int list * int list * refpont list ->
                            (int * int * int * int) list list
- felhok([7, 7, 0, 6, 6, 8, 4],
              [~1, 5, 2, 3, 3, 0, 2, ~1, 4, 2, 2, 4, 2, ~1], []);
> val it =
    [[(1, 1, 2, 3), (1, 8, 2, 9), (1, 11, 2, 12), (4, 1, 6, 2),
      (4, 4, 6, 5), (4, 12, 5, 13), (6, 7, 7, 10)],
     [(1, 2, 2, 3), (1, 7, 2, 8), (1, 10, 2, 12), (4, 1, 6, 2),
      (4, 4, 6, 5), (4, 8, 7, 9), (6, 12, 7, 13)]]
    : (int * int * int * int) list list
Ha viszont a keretprogramot akarom használni, a következő hibaüzenetet kapom:

C:\test>mosmlc -c TFelhok.sml Felhok.sig Felhok.sml KFelhok.sig
                      KFelhok.sml
! Interface mismatch: the implementation of unit Felhok
! does not match its interface, because ...
! Scheme mismatch: value identifier Felhok.felhok
! in the unit Felhok is specified with type scheme
!   val felhok :
  int list * int list * refpont list ->
                      (int * int * int * int) list list
! in the interface
! but its declaration has the unrelated type scheme
!   val felhok :
  int list * int list * refpont/1 list ->
                      (int * int * int * int) list list
! in the implementation
! The declared type scheme should be at least as general
! as the specified type scheme
Mi lehet a hiba oka?

7.1. Válasz.
Oktató: A bajt az okozza, hogy a

datatype refpont  = f of sor * oszlop | e of sor * oszlop
deklaráció (és a hozzátartozó type-deklarációk) nemcsak a TFelhok.sml állományban, hanem a Felhok.sml állományban is előfordulnak. Ha pl. a

type sorosszeg    = int
type oszloposszeg = int
type sor          = int
type oszlop       = int
datatype refpont  = f of sor * oszlop | e of sor * oszlop
deklarációsorozatot kiértékelteti az mosml értelmezővel, majd a

datatype refpont  = f of sor * oszlop | e of sor * oszlop
deklarációt újra kiértékelteti, akkor az mosml ezt válaszolja:

> New type names: =refpont/1
  datatype refpont =
  (refpont/1,con e : int * int -> refpont/1,
              con f : int * int -> refpont/1)
  con e = fn : int * int -> refpont/1
  con f = fn : int * int -> refpont/1
vagyis a refpont egy új típus neve lett (erre utal a refpont/1 jelölés), semmi köze a korábbi azonos nevű típushoz.

Ez még önmagában nem lenne baj (csak felesleges), ha a felhok függvény specifikációjában a TFelhok struktúrában deklarált típusokra hivatkozna a teljes nevükkel, pl. így:

fun felhok (x : TFelhok.radarkep) : TFelhok.felhok list = ...
De hibát okoz, ha a TFelhok szelektort elhagyja:

fun felhok (x : radarkep) ...


Deklaratív programozás - FP-GYIK
2005. március 1.