2012-08-22 28 views
18

quiero definir un operador (llamarlo +-+) que trabaja en esto:La sobrecarga de los operadores

if a,b are Char => a +-+ b = [a][b] 
if a,b are Integer => a +-+ b = a+b 

he intentado con:

class Summable a where 
    (+-+)  :: a -> a -> b 

instance Summable Integer where 
    a +-+ b  = a + b 

instance Summable Char where 
    a +-+ b  = [a] ++ [b] 

pero me da los errores:

Couldn't match type `b' with `Integer'.... 
Couldn't match type `b' with `[Char]' .... 

¿Es posible hacer esto? ¿Cómo?

+1

Tenga en cuenta que '[a] ++ [b]' es simplemente '[a, b]' ... –

Respuesta

25

El problema es que la variable de tipo b no se puede determinar a partir de la instancia, aunque esté corregida. (Tener una variable libre como esa requiere que la función devuelva algo que tenga cualquier tipo, es decir, undefined.)

¿Puede dar +-+ el tipo a -> a -> a? Si es así, haz eso. (Pero parece que esto no es posible.)

De lo contrario, podría usar functional dependencies, de modo que la instancia especifique el tipo de resultado type families, de modo que uno de los atributos de la instanciación sea el tipo de resultado.

Para dependencias funcionales, el código podría ser:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} 

class Summable a result | a -> result where 
    (+-+) :: a -> a -> result 

instance Summable Char String where 
    a +-+ b = [a] ++ [b] 

instance Summable Integer Integer where 
    a +-+ b = a + b 

Para las familias tipo, que sería como:

{-# LANGUAGE TypeFamilies #-} 

class Summable a where 
    type Result a 
    (+-+) :: a -> a -> Result a 

instance Summable Char where 
    type Result Char = String 
    a +-+ b = [a] ++ [b] 

instance Summable Integer where 
    type Result Integer = Integer 
    a +-+ b = a + b 

(Gracias a Vito y Vladimir Matveev para la fijación de los diversos errores ¡Lo había hecho! :))

Cuestiones relacionadas