[Haskell] Comportamento bizzarro, putStr vs putStrLn

Messaggioda kaspar » 03/10/2020, 17:23

Ciao :smt039
Scorporo un pezzo di codice, semplificandolo anche, da una programma inteso per terminale.

Codice:
-- hask.hs

{-
  if you want to try that code by yourself,
  you may need to 'cabal install extra' first
-}
import Data.List.Extra (trim)

-- force the user to type something!
main :: IO ()
main = insertSomething >>= putStrLn . (">>> you\'ve typed: " ++)

insertSomething :: IO String
insertSomething = do putStr ">>> insert something: "
                     h . trim =<< getLine
  where h :: String -> IO String
        h xs = if null xs then insertSomething else return xs


Codice:
$ runghc hask.hs
>>> insert something: something
>>> you've typed: something


Ok, interpretato fa quel che mi aspetto. Lo compilo (con successo)
Codice:
$ ghc hask.hs

e lo provo
Codice:
$ ./hask


niente, un rettangolino sta aspettando che io faccia qualcosa. Nel dubbio batto qualcosa
Codice:
$ ./hask
something
>>> insert something: >>> you've typed: something

Che succede? Doveva chiedermi insert something:, invece no. Ha aspettato che io inserissi qualcosa, per poi farne la richiesta.

Allora provo ad usare putStrLn al posto di putStr in insertSomething (perché non farlo?):

Codice:
-- hask.hs

import Data.List.Extra (trim)

-- force the user to type something!
main :: IO ()
main = insertSomething >>= putStrLn . (">>> you\'ve typed: " ++)

insertSomething :: IO String
insertSomething = do putStrLn ">>> insert something: "
                     h . trim =<< getLine
  where h :: String -> IO String
        h xs = if null xs then insertSomething else return xs


Intepretato fa quel che mi aspetto (va a capo ogni volta, ma fa niente) e , sorpresa!, anche da compilato:
Codice:
$ ./hask
>>> insert something:
ciao
>>> you've typed: ciao


Va bene, cosa non va in putStr? O meglio: mi sfugge qualcosa?
Ultima modifica di kaspar il 03/10/2020, 20:13, modificato 1 volta in totale.
kaspar
Junior Member
Junior Member
 
Messaggio: 143 di 495
Iscritto il: 17/11/2019, 09:58

Re: [Haskell] Comportamento bizzarro, putStr vs putStrLn

Messaggioda solaàl » 03/10/2020, 18:25

A me fa esattamente quello che deve... Che versione di ghc? Usi stack? Che versione?
"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: 563 di 1672
Iscritto il: 31/10/2019, 01:45

Re: [Haskell] Comportamento bizzarro, putStr vs putStrLn

Messaggioda kaspar » 03/10/2020, 18:57

ghc ha versione 8.6.5, versione pacchettizzata da Debian. Tieni conto però che l'ultima versione stabile è 8.10.* e vuoi che non si siano accorti di putStr prima? Può essere.

Bello sapere almeno che per qualcuno funziona.

Può essere anche, adesso l'ho visto, questo (almeno tre anni fa), ma non so cosa sia il buffering... (non sono un informatico, né sto studiando per diventarlo...)

Non uso stack ancora.
kaspar
Junior Member
Junior Member
 
Messaggio: 144 di 495
Iscritto il: 17/11/2019, 09:58

Re: [Haskell] Comportamento bizzarro, putStr vs putStrLn

Messaggioda apatriarca » 05/10/2020, 00:08

Sembra effettivamente un problema di buffering. Significa in pratica che l'output viene scritto nel terminale tutto insieme quando inserisci un carattere di a capo (o dopo un certo numero di caratteri). Viene usato perché la stampa su terminale ha un grosso costo indipendente dal numero di caratteri stampati e si riduce quindi questo costo facendolo più raramente. Tuttavia la richiesta di input da terminale di solito causa la scrittura di tutto quello che era in attesa.

Potrebbe essere un bug di ghc o di qualche altra libreria del tuo sistema.
apatriarca
Moderatore
Moderatore
 
Messaggio: 5497 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [Haskell] Comportamento bizzarro, putStr vs putStrLn

Messaggioda kaspar » 05/10/2020, 08:09

apatriarca ha scritto:Potrebbe essere un bug di ghc o di qualche altra libreria del tuo sistema.

Ho provato cercare qualche parola chiave, e in generale si consiglia di usare hFlush:

Codice:
import Data.List.Extra (trim)
import System.IO (hFlush, stdout)

main :: IO ()
main = putStrLn . (">>> you have typed: " ++) =<< typeSomething

typeSomething :: IO String
typeSomething = h . trim =<< getAnswerOf ">>> type something: "
  where
    h, getAnswerOf :: String -> IO String
    h xs = if null xs
              then typeSomething
              else return xs
    getAnswerOf request = do putStr request
                             hFlush stdout
                             getLine


@solaàl, tu che versione di ghc hai?
kaspar
Junior Member
Junior Member
 
Messaggio: 146 di 495
Iscritto il: 17/11/2019, 09:58

Re: [Haskell] Comportamento bizzarro, putStr vs putStrLn

Messaggioda solaàl » 05/10/2020, 08:31

Codice:
The Glorious Glasgow Haskell Compilation System, version 8.10.2
"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: 564 di 1672
Iscritto il: 31/10/2019, 01:45


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite