2010-08-27 8 views
7

Los programadores de Ocaml pueden usar los llamados "tipos fantasma" para aplicar algunas restricciones utilizando el sistema de tipo. Un buen ejemplo se puede encontrar en http://ocaml.janestreet.com/?q=node/11.Implementación de tipos fantasma en F #

La sintaxis type readonly no funciona en F #. Podría ser reemplazado por un tipo pseudo-fantasma definido como type readonly = ReadOnlyDummyValue para implementar los trucos en la publicación de blog mencionada anteriormente.

¿Existe alguna forma mejor de definir los tipos fantasma en F #?

+4

¿Has leído http://blog.matthewdoig.com/?p=134 y http://blog.matthewdoig.com/?p=138? –

+0

Gracias por los enlaces. De alguna manera me los perdí. –

+1

El blog de matthewdoig está muerto, pero los artículos están en archive.org: http://web.archive.org/web/20100615031828/http://blog.matthewdoig.com/?p=134 http: //web.archive .org/web/20100615031841/http: //blog.matthewdoig.com/? p = 138 –

Respuesta

14

Creo que la definición del tipo simplemente usando type somename no funcionará en F #. El compilador F # necesita generar algún tipo .NET a partir de la declaración y la especificación F # no define explícitamente lo que debería suceder para los tipos fantasma.

Puede crear un tipo concreto (por ejemplo, con type somename = ReadOnlyDummyValue) en el archivo de implementación (.fs) y ocultar las partes internas del tipo agregando solo type somename al archivo de interfaz (.fsi). De esta forma, te acercarás bastante a un tipo fantasma: el usuario que se encuentre fuera del archivo no verá las partes internas del tipo.

Otra alternativa atractiva sería utilizar interfaces. Esto me suena lógico, porque la interfaz vacía es probablemente el tipo más simple que puede declarar (y no introduce ningún identificador ficticio). interfaz de vacío se ve así:

type CanRead = interface end 
type CanWrote = interface end 

Lo interesante, en este caso, es que también se puede crear interfaces heredadas:

type CanReadWrite = 
    inherit CanRead 
    inherit CanWrite 

A continuación, puede escribir una función que puede tomar valores de tipo Ref<CanRead, int> sino también valores de tipo Ref<CanReadWrite, int> (porque estos valores también son compatibles con la lectura):

let foo (arg:Ref<#CanRead, int>) = // ...  

Esto parece como algo que podría ser u seful. En realidad, me interesaría mucho si esto también se puede hacer en OCaml (porque depende del soporte F # para las interfaces y la herencia).

+0

La sugerencia de usar interfaces es excelente. ¡Gracias! –

+0

@Tomas: Eso también se puede hacer en OCaml, por supuesto. –

+0

@Jon: esperaba eso. Simplemente no sabía cómo y no podía encontrar ninguna buena fuente de información. ¿Tiene un enlace a algún ejemplo (de preferencia disponible libremente ;-))? –

Cuestiones relacionadas