Sto aiutando un amico a imparare Haskell e di recente ha creato un codice come questo, che controlla e genera un ciclo di masterizzazione della CPU in fase di runtime. Sono completamente sconcertato da questo.Perché l'importazione di Control.Applicative consente a questo codice errato di digitare il controllo?
import Control.Monad
import Control.Applicative
main = forever putStrLn "Hello, infinity"
che non deve digitare controllare, ma lo fa. La versione corretta sarebbe chiaramente:
main = forever $ putStrLn "Hello, infinity"
Cosa c'è di strano e sorprendente per me è che si ottengono risultati diversi con e senza l'importazione Control.Applicative. Senza l'importazione, non tipo si verifica:
Prelude Control.Monad> forever putStrLn "Hello, infinity"
<interactive>:1:1:
No instance for (Monad ((->) String))
arising from a use of `forever'
Possible fix: add an instance declaration for (Monad ((->) String))
In the expression: forever putStrLn "Hello, infinity"
In an equation for `it': it = forever putStrLn "Hello, infinity"
non vedo un'istanza Monade per ((->) String
nel sorgente per Control.Applicative, quindi sto cercando di indovinare qualcosa di strano sta accadendo a causa del suo uso di Control.Category o Control.Arrow, ma non lo so. Quindi credo che ho due domande:
- Che cosa è circa l'importazione di Control.Applicative che lascia che questo accada?
- Cosa succede quando entra nel ciclo infinito? Che cosa sta cercando di eseguire Haskell in questo caso?
Grazie,
Puoi approfondire su cosa è utile l'istanza per '(->) e'? –
@DanielLyons È utile quando si hanno molte funzioni che hanno tutte bisogno di accedere ad alcune informazioni di configurazione condivise. Quindi puoi scrivere (ad esempio) 'foo >> = bar >> = baz' invece di ripetere l'ambiente ovunque come in' \ e -> lascia x = foo e; y = bar x e; z = baz y e in y'. –