2010-06-05 5 views

Respuesta

21

Parece que only in superficial ways son interfaces de Go, como clases de tipo de parámetro único (clases de constructor) en Haskell.

  • métodos están asociados con un tipo de interfaz
  • objetos (tipos particulares) pueden tener implementaciones de esa interfaz

No está claro para mí si Ir en cualquier forma compatible con el polimorfismo acotada a través de interfaces, que es el objetivo principal de las clases de tipos. Es decir, en Haskell, los métodos de la interfaz se puede usar en diferentes tipos,

class I a where 
    put :: a -> IO() 
    get :: IO a 

instance I Int where 
    ... 

instance I Double where 
    .... 

Así que mi pregunta es si Go es compatible con el tipo de polimorfismo. Si no, en realidad no son como clases de tipos. Y no son realmente comparables.

Las clases de tipos de Haskell permiten una poderosa reutilización de código a través de "genéricos" - polimorfismo de mayor grado de afinidad - una buena referencia para cross-language support for such forms of generic program is this paper.

Ad hoc, o polimorfismo acotado, a través de clases de tipo, es well described here. Este es el objetivo principal de las clases de tipos en Haskell, y una no abordada a través de las interfaces de Go, lo que significa que no son realmente muy similares en absoluto. Las interfaces son estrictamente menos poderosas, una clase de tipo de orden cero.

+4

De hecho, la única relación entre los dos parece ser que en ambos casos los "métodos" viven independientemente de las "clases". Eso es todo. –

+2

Las interfaces de Go admiten el "polimorfismo limitado", como se define estrictamente en ese artículo de Wikipedia, en virtud de simplemente nombrar la interfaz que desea en la firma de una función. Por ejemplo, si escribo "func foo (a, b IBar)", el compilador se asegura de que solo puedo pasar las estructuras que soportan IBar. Sin embargo, las clases de tipos de Haskell admiten tipos no estructurales, e incluso enlaces compuestos (por ejemplo, func foo (a, b (IBar && IBaz)) es ilegal en Go, pero (IBar a, IBaz a) => foo :: a -> b -> ... es perfectamente legal). Tendría que hacer una interfaz compuesta en Ir para hacer algo similar (vis. Io.ReadCloser). –

6
  1. en Haskell instanciación clase de tipos es explícita (es decir, que tiene que decir instance Foo Bar de barra a una instancia de Foo), mientras que en marcha la implementación de una interfaz está implícita (es decir, cuando se define una clase que define los métodos adecuados, implementa automáticamente la interfaz correspondiente sin tener que decir algo como implement InterfaceName).
  2. Una interfaz solo puede describir métodos donde la instancia de la interfaz es el receptor. En una clase de tipo, el tipo de instancia puede aparecer en cualquier posición de argumento o el tipo de retorno de una función (es decir, si Foo es una instancia de tipo Bar debe existir una función llamada baz, que toma un Int y devuelve un Foo - no puedes decir eso con interfaces).
+4

La falta de polimorfismo restringe en gran medida el grado en que las interfaces Go están relacionadas con las clases de tipos. Diría que sin polimorfismo en los métodos de instancia, en realidad no están relacionados, aparte de superficialmente. –

+0

Lo que la gente pregunta al respecto muestra claramente que están relacionados. Diría que las interfaces Go son un subconjunto estricto de lo que ofrecen las clases de tipos de Haskell. Por ejemplo, todo lo que puedes hacer en Go es posible en Haskell (trivialmente, incluso), pero lo contrario no es verdad. –

5

Similitudes muy superficiales, las interfaces de Go son más parecidas a la subtipificación estructural en OCaml.

6

Agregaré a la excelente respuesta de Don Stewart que una de las sorprendentes consecuencias de las clases de tipos de Haskell es que puede usar la programación lógica en tiempo de compilación para generar arbitrariamente muchas instancias de una clase. (El sistema de clase de Haskell incluye lo que es efectivamente un subconjunto sin cortes de Prolog, muy similar a Datalog). Este sistema se explota con gran efecto en la biblioteca QuickCheck. O para un ejemplo muy simple, puede ver cómo definir un version of Boolean complement (not) that works on predicates of arbitrary arity. Sospecho que esta habilidad fue una consecuencia involuntaria del sistema de tipo de clase, pero ha demostrado ser increíblemente poderosa.

Go no tiene nada como eso.

3

C++ Concepts (que no llegó a C++ 0x) son como las clases de tipo Haskell. También hubo "axiomas" que no están presentes en absoluto en Haskell. Te permiten formalizar cosas como las leyes de la mónada.