2011-01-07 14 views
26

Cosa c'è di sbagliato in questa funzione?errore variabile di tipo rigido

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

String è un'istanza della classe Show, quindi sembra corretta.

L'errore è

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" 

risposta

31

test :: Foo a => a significa "per qualsiasi tipo che è un'istanza di Foo, test è un valore di quel tipo". Pertanto, in qualsiasi luogo in cui è possibile utilizzare un valore di tipo X dove X è un'istanza Foo, è possibile utilizzare un valore di tipo Foo a => a.

Qualcosa di simile test :: Num a => a; test = 42 opere perché 42 può essere un valore di tipo Int o Integer o Float o qualsiasi altra cosa che è un'istanza di Num.

Tuttavia "asdasd" non può essere un qualcosa di Int oppure che è un'istanza di Show - si può sempre e solo essere un String. Di conseguenza non corrisponde al tipo Show s => s.

+1

In GHC con estensione di linguaggio 'OverloadedStrings' e importazione' Data.String', è anche possibile utilizzare la firma 'test :: IsString s ⇒ s'. – Conal

+0

'test :: Num => a' diverso da' test :: Num'? –

+2

@mcb Dipende da come si definisce "diverso". Sono entrambi errori, quindi in questo senso sono uguali. Comunque potresti obiettare che sono diversi perché presumibilmente sono il risultato di diversi errori. Questo è 'test :: Num => a' potrebbe essere il risultato di un semplice refuso (dimenticando' a' prima di '=>'), mentre 'test :: Num' è presumibilmente il risultato dell'autore del codice che pensa che 'Num' è un tipo e non una classe di tipo. – sepp2k

6

Sì, String è un'istanza di Show. Ma ciò non consente l'utilizzo di una stringa come valore abituale Show. 1 può essere Num a => a perché c'è un 1 :: Integer, un 1 :: Double, un 1 :: Word16, ecc Se "asdasd" potrebbe essere di tipo Show a => a, non ci sarebbe "asdasd" :: Bool, "asdasd" :: String, "asdasd" :: Int, ecc Non c'è. Pertanto, "asdasd" non può essere di tipo Show a => a. Il tipo di costante di una stringa non diventa molto più generale di String.

Problemi correlati