2010-06-07 20 views
10

Sono un principiante interessato a Haskell, e ho cercato di implementare la flatmap (>> =) da solo per comprenderlo meglio. Attualmente hoHaskell FlatMap

flatmap :: (t -> a) -> [t] -> [a] 
flatmap _ [] = [] 
flatmap f (x:xs) = f x : flatmap f xs 

che implementa la parte "mappa" ma non quella "piatta".
La maggior parte delle modifiche che rendono risultato nell'errore avvilente e abbastanza informationless

Occurs check: cannot construct the infinite type: a = [a] 
    When generalising the type(s) for `flatmap' 

.

Cosa mi manca?

+3

BTW, c'è una Wikipedia che descrive quale verifica si verifica: http://en.wikipedia.org/wiki/Occurs_check – jrockway

risposta

19

Un errore come questo si verifica quando la firma del tipo specificato non corrisponde al tipo effettivo della funzione. Dal momento che non è stato mostrare il codice che causa l'errore, devo immaginare, ma presumo si è cambiato in qualcosa di simile a questo:

flatmap _ [] = [] 
flatmap f (x:xs) = f x ++ flatmap f xs 

Che guarda caso, è perfettamente corretto. Tuttavia, se si è dimenticato di modificare la firma del tipo, si verificherà quanto segue:

Il controllo del tipo vede che si utilizza ++ sui risultati di f x e flatmap f xs. Poiché ++ funziona su due elenchi dello stesso tipo, il correttore di tipi ora sa che entrambe le espressioni devono valutare elenchi dello stesso tipo. Ora il typechecker sa anche che flatmap f xs restituirà un risultato di tipo [a], quindi f x deve anche avere il tipo [a]. Tuttavia nella firma del tipo si dice che f ha tipo t -> a, quindi f x deve avere il tipo a. Questo porta il controllo del tipo a concludere che [a] = a è una contraddizione e porta al messaggio di errore che vedi.

Se si modifica la firma del tipo su flatmap :: (t -> [a]) -> [t] -> [a] (o lo si rimuove), funzionerà.

+0

Grazie. Questo era esattamente il mio problema. –

+0

A volte capita anche se non si specifica una firma del tipo. – Martijn