2011-01-07 14 views
26

¿Qué hay de malo con esta función?tipo rígido error variable

test :: Show s ⇒ s 
test = "asdasd" 

Cadena es una instancia de la clase Show, por lo que parece correcta.

El error es

src\Main.hs:224:7: 
    Couldn't match expected type `s' against inferred type `[Char]' 
     `s' is a rigid type variable bound by 
      the type signature for `test' at src\Main.hs:223:13 
    In the expression: "asdasd" 
    In the definition of `test': test = "asdasd" 

Respuesta

31

test :: Foo a => a medios "para cualquier tipo que es una instancia de Foo, test es un valor de ese tipo". Entonces, en cualquier lugar donde pueda usar un valor de tipo X donde X es una instancia Foo, puede usar un valor de tipo Foo a => a.

Algo así como test :: Num a => a; test = 42 42 obras porque puede haber un valor de tipo Int o Integer o Float o cualquier otra cosa que es una instancia de Num.

Sin embargo "asdasd" no puede ser una cosa Int o de lo que es una instancia de Show - que sólo puede ser jamás un String. Como consecuencia, no coincide con el tipo Show s => s.

+1

En GHC con la extensión de lenguaje 'OverloadedStrings' e importar' Data.String', también puede usar la firma 'test :: IsString s ⇒ s'. – Conal

+0

¿'test :: Num => a' es diferente de' test :: Num'? –

+2

@mcb Eso depende de cómo se defina "diferente". Ambos son errores, entonces en ese sentido son lo mismo. Sin embargo, podría argumentar que son diferentes porque presumiblemente son el resultado de diferentes errores. Es decir 'test :: Num => a' podría ser el resultado de un simple error tipográfico (olvidando el' a' antes de '=>'), mientras que 'test :: Num' es presumiblemente el resultado del autor del código que piensa que 'Num' es un tipo y no una clase de tipo. – sepp2k

6

Sí, String es una instancia de Show. Pero eso no permite usar una cadena como un valor Show abritary. 1 puede haber Num a => a porque hay un 1 :: Integer, un 1 :: Double, un 1 :: Word16, etc. Si "asdasd" podría ser de tipo Show a => a, no habría "asdasd" :: Bool, "asdasd" :: String, "asdasd" :: Int, etc. No hay. Por lo tanto, "asdasd" no puede ser del tipo Show a => a. El tipo de constante de cadena no es mucho más general que String.

Cuestiones relacionadas