Domanda

Sto usando GHCi (versione 6.12.3) per giocare un po 'con Haskell.Recentemente ho letto di funtori e funtori applicativi pensato che se non si potesse implementare qualcosa di simile al <*> dei funtori applicativi utilizzando solo le primitive del funtore.Dopo averci pensato un po ', mi è venuto in mente fmap fmap che avrebbe un tipo (quasi) ideale di

Functor f => f (a -> b) -> f (f a -> f b) o più genericamente

(Functor f1, Functor f2) => f1 (a -> b) -> f1 (f2 a -> f2 b)

Ho provato

let q = fmap fmap

Ho ricevuto il seguente errore

<interactive>:1:8:
    Ambiguous type variable `f1' in the constraint:
      `Functor f1' arising from a use of `fmap' at <interactive>:1:8-16
    Probable fix: add a type signature that fixes these type variable(s)

<interactive>:1:13:
    Ambiguous type variable `f' in the constraint:
      `Functor f' arising from a use of `fmap' at <interactive>:1:13-16
    Probable fix: add a type signature that fixes these type variable(s)

Scrivere la firma del tipo sopra come suggerito non ha aiutato. La cosa più pazza è che quando ho digitato :t fmap fmap ho ottenuto un tipo equivalente come sopra.

Cosa sto facendo di sbagliato?Perché fmap fmap restituisce un errore di tipo sebbene GHCi trovi un tipo per esso?

È stato utile?

Soluzione

Sembra che tu stia incappando nella restrizione sul monomorfismo .

Provare il tuo esempio in GHCi con -XNoMonomorphismRestriction fornisce il risultato atteso.

Puoi anche sovvertirlo scrivendo let f x = fmap fmap $ x.La restrizione sul monomorfismo si applica solo alle definizioni di primo livello che "assomigliano" a valori, ad esempio f = something, quindi l'introduzione di un argomento esplicito fa sì che non si applichi più.Inoltre, non si applicherebbe se questo non fosse al livello più alto (ad esempio in una clausola where).Per ulteriori dettagli, vedere il collegamento.

Altri suggerimenti

Non posso ancora commentare ovunque, quindi posterò una risposta.Come accennato in precedenza, l'errore che stai ricevendo è dovuto alla restrizione del monomorfismo.Fissare la firma del tipo a uno dei due dati nella domanda originale rende effettivamente ghci felice come speravi, forse hai appena sbagliato la sintassi?

Prelude> let q :: (Functor f) => f (a -> b) -> f (f a -> f b); q = fmap fmap
Prelude> :t q
q :: (Functor f) => f (a -> b) -> f (f a -> f b)

Prelude> let q :: (Functor f1, Functor f2) => f1 (a -> b) -> f1 (f2 a -> f2 b); q = fmap fmap
Prelude> :t q
q :: (Functor f1, Functor f2) => f1 (a -> b) -> f1 (f2 a -> f2 b)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top