2012-10-15 14 views
6

Zrobiłem funktor dla zestawów wielkoformatowych-stanie, w następujący sposób:Rozszerzanie SML Mapy do formattable Mapy

module type POrderedType = 
    sig 
    type t 
    val compare : t -> t -> int 
    val format : Format.formatter -> t -> unit 
    end 

module type SET = 
    sig 
    include Set.S 
    val format : Format.formatter -> t -> unit 
    end 

module MakeSet (P : POrderedType) : SET with type elt = P.t 

Realizacja tego jest prosta:

module MakeSet (P : OrderedType) = 
    struct 
    include Set.Make(P) 

    let format ff s = 
     let rec format' ff = function 
     | [] ->() 
     | [v] -> Format.fprintf ff "%a" format v 
     | v::tl -> Format.fprintf ff "%a,@ %a" format v format' tl in 
     Format.fprintf ff "@[<4>%[email protected]]" format' (elements s) 
    end 

chciałem zrobić coś podobnego z mapy. POrderedType jest w porządku na klucze, ale muszę prostszy typ dla wartości:

module type Printable = 
    sig 
    type t 
    val format : Format.formatter -> t -> unit 
    end 

Następnie chciałem zrobić coś podobnego do tego, co zrobił dla zestawów, ale biegnę do następującego problemu. Map.S wartości mają typ +'a t. Nie mogę znaleźć sposobu na uwzględnienie definicji Map.S, ograniczając wartość 'a, aby była to Printable.t. Co chcę jest coś następnego (pomijając fakt, że jest to nielegalne):

module MakeMap (Pkey : POrderedType) (Pval : Printable) : 
    MAP with type key = Pkey.t and type 'a t = 'a t constraint 'a = Pval.t 

Czy istnieje jakiś sposób, aby robić to, co chcę bez kopiowania całą podpis mapą ręcznie?

Odpowiedz

3

Myślę, że najczystszym sposobem zaproponowania funkcji drukowania dla map polimorficznych jest uczynienie funkcji drukowania mapy parametryczną względem funkcji drukowania wartości. Można myśleć o tym w ten sposób:

  • rodzaje funktor zdefiniowane są zdefiniowane na poziomie funktora, więc zapewniając funkcje dla nich najlepiej wykonać poprzez dodanie nowych parametrów funktora (lub wzbogacenie istniejących)

  • parametryczne typy są związani (uogólniony) na poziomie wartości, tak zapewniając funkcje dla nich najlepiej zrobić poprzez dodanie nowych parametrów do wartości

W SML, wygoda mają tendencję, aby ludzie faworyzują polimorfizm parametryczny nad functorization gdy Possi ble. Funkcjonalizacja czasami jest niezbędna do wymuszenia pewnego rodzaju bezpieczeństwa (tutaj jest używana, aby upewnić się, że mapy różnych funkcji porównania mają niekompatybilne typy), ale poza tym ludzie raczej próbują mieć polimorfizm. Więc masz szczęście w tej sytuacji.

Jeśli naprawdę chcesz, aby funktor tworzył mapy monomorficzne, obawiam się, że będziesz musiał skopiować cały interfejs mapy i dostosować go w przypadku momonorficznym - to nie jest dużo pracy.