[Haskell] Dubbio IO...

Messaggioda kaspar » 20/09/2020, 20:10

Ciao :smt039
Iniziamo con un pezzo di un codice più vasto e scorporato per quello che mi serve sapere.

Codice:
-- questo è il file Cfg.hs

module Cfg where

import Control.Monad (liftM)
import Control.Conditional (ifM)
import System.Directory (doesFileExist)
import System.Environment.FindBin (getProgPath)

type Maybe2 a = (Maybe a, Maybe a)

getCfgs :: IO [Maybe2 String]
getCfgs = do
    thisFile <- liftM (++ "/configs") getProgPath
    ifM (doesFileExist thisFile)
        (liftM (map chop . lines) (readFile thisFile))
        (return [])
  where
    chop :: String -> Maybe2 String
    chop str = case words str of
                 x:y:_ -> (Just x , Just y)
                 x:[]  -> (Just x , Nothing)
                 _     -> (Nothing, Nothing)

getCfgValOf :: String -> IO (Maybe String)
getCfgValOf key = liftM h getCfgs
  where
    h :: [Maybe2 String] -> Maybe String
    h [] = Nothing
    h ((a, b):xs) | a == Just key = b
                     | otherwise     = h xs


In realtà in questo caso non è cruciale sapere cose fanno le funzioni, piuttosto sapere i tipi delle cose.

Testo nascosto, fai click qui per vederlo
Comunque sia, per l'esempio, consideriamo un file chiamato config nella stessa cartella del progamma col main :: IO () come sotto1

Codice:
GRUB_DEFAULT               0
GRUB_TIMEOUT_STYLE         hidden
GRUB_TIMEOUT               0
GRUB_CMDLINE_LINUX_DEFAULT quiet


Codice:
$ ghci
> :load Cfg.hs
> getCfgValOf "GRUB_TIMEOUT_STYLE"
Just "hidden"
> getCfgValOf "GRUB_CMDLINE_LINUX_DEFAULT"
Just "quiet"


Prendiamo un main così

Codice:
import Cfg (getCfgValOf)

main :: IO ()
main =  mapM printCfgValOf [ "GRUB_DEFAULT"
                           , "GRUB_TIMEOUT_STYLE"
                           , "GRUB_TIMEOUT"
                           , "GRUB_CMDLINE_LINUX_DEFAULT"
                           ]
  where printCfgValOf :: String -> IO ()
        printCfgValOf key = print =<< getCfgValOf key


Mi chiedo che fine faccia quel getCfgs :: IO (Maybe2 String) richiamato da definizione dietro le quinte ben quattro volte consecutive. Mi sto riferendo a questo pezzo su Real World Haskell

What Is An I/O Action?
Actions:
[...]
* Produce an effect when performed, but not when evaluated. That is, they only produce an effect when called by something else in an I/O context.
[...]


Cosa fa il calcolatore? È un IO qualcosa, quindi da manuale dovrebbe aspettare di essere incastrato in un contesto I/O per fare un qualcosa: e questo qualcosa è restituire una particolare lista. Ma da una chiamata alla successiva che succede, viene rifatto di volta in volta tutto il computo che definisce getCfgs? Credo anche di non essere riuscito ad intendere perfettamente la differenza tra i due termini in corsivo in questo caso.

Note

  1. Il contenuto è puramente casuale.
Ultima modifica di kaspar il 21/09/2020, 15:27, modificato 1 volta in totale.
kaspar
Junior Member
Junior Member
 
Messaggio: 139 di 495
Iscritto il: 17/11/2019, 09:58

Re: [Haskell] Dubbio IO...

Messaggioda solaàl » 20/09/2020, 21:09

Può essere che la differenza tra i due termini in corsivo sia la differenza tra lazy evaluation e non-lazy?
"In verità le cose che nella vita sono tenute in gran conto si riducono a vanità, o putredine di nessun valore; botoli che si addentano, bambocci litigiosi che ora ridono, poi tosto piangono." (Lotario conte di Segni)
Avatar utente
solaàl
Senior Member
Senior Member
 
Messaggio: 547 di 1672
Iscritto il: 31/10/2019, 01:45

Re: [Haskell] Dubbio IO...

Messaggioda apatriarca » 21/09/2020, 05:35

Per prima cosa tutto viene valutato usando la lazy evaluation in Haskell a meno di fare uso di particolari costrutti che forzano la valutazione di una espressione. Non si tratta quindi di lazy evaluation vs strict evaluation.

Quello che si dice in questo caso è diverso ed è in qualche modo uguale per tutti i monadi. Per spiegarlo è in effetti forse più semplice considerare un altro tipo di monade: ((->) e) (le funzioni con primo argomento fissato). Possiamo pensare a questo monade come ad un insieme di "azioni" eseguite all'interno di un determinato ambiente di tipo e. Una funzione in questo monade non produce alcun valore, ma solo una funzione che, quando il suo valore sarà infine richiesto, produrrà qualcosa. IO è simile nel senso che produrrà un risultato solo quando richiamata direttamente o indirettamente (attraverso funzioni a loro volta nel monade IO) dal main (oppure qualcosa che fa uso di unsafePerformIO).
apatriarca
Moderatore
Moderatore
 
Messaggio: 5484 di 10438
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [Haskell] Dubbio IO...

Messaggioda apatriarca » 21/09/2020, 05:54

Solo una piccola nota sul libro da te scelto. È stato pubblicato nel 2008 e Haskell è cambiato molto negli anni. In effetti l'ultima versione standard del linguaggio è del 2010 e una nuova versione è prevista a breve.. La principale modifica consiste in una esplosione di typeclasses inspirate alla teoria delle categorie che si possono per esempio trovare qui. Più di recente ci sono le librerie "ottiche" che sono per esempio spiegate qui.
apatriarca
Moderatore
Moderatore
 
Messaggio: 5485 di 10438
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [Haskell] Dubbio IO...

Messaggioda kaspar » 21/09/2020, 15:22

Sì, è tutto lazy. Ho provato a spiegarmi la differenza tra quei due termini. Un caso molto più stupido è questo: 2 + 3 in un linguaggio come Python, viene bellamente valutato senza pensarci un secondo in 5. Haskell invece di base pensa a non performare l'addizione, preferendosi portare a spasso (+) 2 3 così com'è (destinandogli uno thunk di memoria). Bisogna costringerlo a eseguire il calcolo.
Principalmente faccio fatica a rappresentarmi le cose di tipo IO qualcosa, e questo è il caso.

Codice:
getCfgs :: IO [Maybe2 String]
getCfgs = do
    thisFile <- liftM (++ "/configs") getProgPath
    ifM (doesFileExist thisFile)
        (liftM (map chop . lines) (readFile thisFile))
        (return [])
  where
    chop :: String -> Maybe2 String
    chop str = case words str of
                 x:y:_ -> (Just x , Just y)
                 x:[]  -> (Just x , Nothing)
                 _     -> (Nothing, Nothing)


L'evaluation di getCfgs cos'è? Il sapere come è definito, ma non fare niente nel momento in cui, definito, viene valutato a qualcosa. Questo, sempre destinando, dello spazio di meoria per quello che si trascina dietro. Invece in contesto IO, viene eseguito, e sputa fuori un risultato (una IO lista).
Essendo l'altra funzione così come l'ho data, getCfgs valutato non fa nulla, chiamato da getCfgValOf all'interno di un main, è costretto a fare qualcosa. Ma tra una chiamata e la successiva che succede?

Codice:
import Cfg

main :: IO ()
main = do
   print =<< getCfgValOf "GRUB_DEFAULT"
   print =<< getCfgValOf "GRUB_TIMEOUT_STYLE"
   print =<< getCfgValOf "GRUB_TIMEOUT"
   print =<< getCfgValOf "GRUB_CMDLINE_LINUX_DEFAULT"


Viene forzato a rifare la stessa cosa ogni volta (buttare fuori una IO lista)? Oppure mantiene memoria di quello che ha fatto, e non ricalcola la stessa cosa successivamente?
kaspar
Junior Member
Junior Member
 
Messaggio: 140 di 495
Iscritto il: 17/11/2019, 09:58

Re: [Haskell] Dubbio IO...

Messaggioda kaspar » 21/09/2020, 15:34

apatriarca ha scritto:Solo una piccola nota sul libro da te scelto. È stato pubblicato nel 2008 e Haskell è cambiato molto negli anni.


Lo so bene. Il testo è stato scelto con lo scopo di incominciare a fare qualcosa di molto pratico da subito. Per quanto riguarda la teoria sottostante, studiando Teoria delle Categeorie ho occasione di sistemare le idee e di affinare i miei programmini. Quindi diciamo che di quel libro, tengo molte cose, ne rifiuto altre (l'espressione "teoria delle categoria" compare forse un paio di volte in tutto il libro, "funtore" non credo più volte).
Ultima modifica di kaspar il 21/09/2020, 15:37, modificato 1 volta in totale.
kaspar
Junior Member
Junior Member
 
Messaggio: 141 di 495
Iscritto il: 17/11/2019, 09:58

Re: [Haskell] Dubbio IO...

Messaggioda apatriarca » 21/09/2020, 15:35

Da un certo punto di vista IO è "magico" in haskell nel senso che la sua reale definizione vive al di fuori del linguaggio nel compilatore che trasforma quelle operazioni in qualcosa che viene eseguito ad un certo punto come in Python. Un monade fornisce una astrazione sulla vera natura dell'ambiente in cui esegui le tue azioni.

Credo che tutto venga eseguito più volte sinceramente, ma potrei in effetti sbagliarmi che non sono così esperto di queste cose. L'unico modo per essere certi è guardare l'output del compilatore.
apatriarca
Moderatore
Moderatore
 
Messaggio: 5488 di 10438
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [Haskell] Dubbio IO...

Messaggioda apatriarca » 21/09/2020, 15:38

Una piccola nota sulla teoria delle categorie, ci sono diverse differenze tra i corrispondenti concetti in Haskell e matematica. Le definizioni sono infatti spesso diverse. Il Funtore in Haskell è per esempio un Endofuntore in matematica. La scelta delle funzioni fondamentali della definizione di un monade è diversa nelle due teorie..
apatriarca
Moderatore
Moderatore
 
Messaggio: 5489 di 10438
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [Haskell] Dubbio IO...

Messaggioda solaàl » 21/09/2020, 15:54

apatriarca ha scritto:Una piccola nota sulla teoria delle categorie, ci sono diverse differenze tra i corrispondenti concetti in Haskell e matematica. Le definizioni sono infatti spesso diverse. Il Funtore in Haskell è per esempio un Endofuntore in matematica. La scelta delle funzioni fondamentali della definizione di un monade è diversa nelle due teorie..

La definizione di monade è equivalente a quella matematica; per la prima osservazione, il motivo è che esiste un solo kind per i tipi: sai se questa cosa è stata/verrà cambiata in versioni più recenti, inserendo una maniera di "stratificare" gli universi, anche vedendo come viene gestita in Agda/Idris?
"In verità le cose che nella vita sono tenute in gran conto si riducono a vanità, o putredine di nessun valore; botoli che si addentano, bambocci litigiosi che ora ridono, poi tosto piangono." (Lotario conte di Segni)
Avatar utente
solaàl
Senior Member
Senior Member
 
Messaggio: 548 di 1672
Iscritto il: 31/10/2019, 01:45

Re: [Haskell] Dubbio IO...

Messaggioda apatriarca » 21/09/2020, 18:55

Non ho idea di cosa sia in programma per la nuova versione di Haskell..
apatriarca
Moderatore
Moderatore
 
Messaggio: 5491 di 10438
Iscritto il: 08/12/2008, 20:37
Località: Madrid


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite