2009-06-09 7 views
8

Il mostrano funzione in Haskell non sembra fare quello che dovrebbe:Haskell: Show avvitato?

Prelude> let str = "stack\n\noverflow" 
Prelude> putStrLn str 
stack 


overflow 
Prelude> show str 
"\"Stack\\n\\n\\noverflow\"" 
Prelude> 

Quando dichiaro funzioni, io di solito mettere le firme di tipo come Mostra, che non si occupa correttamente con a capo . Voglio trattare lo \n come newline, non letteralmente "\n". Quando cambio il tipo in String, le funzioni funzionano correttamente. Ma avrei dovuto implementare una funzione separata per gli interi, galleggianti, ecc, ecc

Per esempio, posso dichiarare una funzione:

foo :: (Show x) => x -> IO() 
foo x = do 
    putStrLn $ show x 

... e lo chiamo in questo modo:

foo "stack\n\noverflow" 
foo 6 
foo [1..] 

Come si ottiene la funzione per restituire cosa è previsto? Cioè quale funzione è simile a show ma può restituire stringhe contenenti newline?

+1

puoi darci un caso di questo uso specifico? Renderebbe più facile comprendere la tua intenzione. – Martijn

+0

Si potrebbe semplicemente aggiungere un segno di spunta per vedere se l'input è una stringa, e basta stamparlo. La corrispondenza di modelli è una cosa molto utile. – Rayne

+1

"show" è come 'repr()' in Python e 'inspect' in Ruby, se hai già usato quelle lingue. –

risposta

14

Il contratto del metodo show in Haskell è che produce una stringa che, una volta valutata, restituisce il valore mostrato.

Prelude> let str = "stack\n\noverflow" 
Prelude> putStrLn str 
stack 

overflow 
Prelude> putStrLn (show str) 
"stack\n\noverflow" 
Prelude> 
+2

Solo per aggiungere a questo, la funzione che hai descritto si chiama "stampa" che è effettivamente definita proprio come sopra stampa x = putStrLn (mostra x) – Phyx

3

show mostra la variabile nel modo in cui è stata inserita.

Sembra abbastanza normale per me.

9

Suona come si sta cercando di simulare un metodo ToString, anche se alcuni di vostra terminologia è un po 'di confusione.

è possibile simulare in questo modo:

{-# LANGUAGE UndecidableInstances, OverlappingInstances, 
      FlexibleInstances, TypeSynonymInstances #-} 

class ToString a where 
    toString :: a -> String 

instance ToString String where 
    toString = id 

instance Show a => ToString a where 
    toString = show 

Tuttavia, come dimostrano i pragma linguaggio, questo non è molto desiderabile. Per avere un'idea di ciò che stai cercando di fare sarebbe più facile se avessimo più contesto ...

1

Non sono davvero sicuro del punto in quello che stai cercando di fare. Sarebbe d'aiuto se chiarissi un po '. Show sta facendo quello che dovrebbe fare. Show produce semplicemente una stringa contenente ciò che è stato mostrato.

1

Il piano di Porges funziona e penso che esalti mette in evidenza ciò che show è davvero all'altezza, dal momento che il comportamento confuso trovato in ghci si presenterà ancora se si ottiene la funzione IO desiderata. Nota che ho aggiunto un'istanza per il codice di Char to Porges, dal momento che presumibilmente vorrai che non ci siano preventivi.

{-# LANGUAGE UndecidableInstances, OverlappingInstances, 
     FlexibleInstances, TypeSynonymInstances #-} 
class ToString a where 
    toString :: a -> String 

instance ToString String where 
    toString = id 

instance ToString Char where 
    toString x = [x] 

instance Show a => ToString a where 
    toString = show 

foo :: (ToString a) => a -> IO() 
foo x = do {putStrLn $ toString x} 

poi, in ghci, guardare ciò che accade con foo.show: "la cui funzione è simile a show ma può tornare stringhe contenente a capo"

*Main> let str = "stack\n\noverflow" 
*Main> show str 
"\"stack\\n\\noverflow\""  
*Main> putStrLn str 
stack 

overflow 
*Main> putStrLn (show str) 
"stack\n\noverflow" 
*Main> foo str 
stack 

overflow 
*Main> foo (show str) 
"stack\n\noverflow" 
*Main> foo (show (show str)) 
"\"stack\\n\\noverflow\"" 
*Main> let newl = "\n" 
*Main> foo newl 


*Main> putStrLn newl 


*Main> putStrLn (show newl) 
"\n" 



*Main> foo (show newl) 
"\n" 
*Main> foo (show (show newl)) 
"\"\\n\"" 
*Main> 
0

Risposta: id

+0

Stai solo cercando di essere divertente o non hai appena risposto alla domanda? – Jasper

+0

Questo è piuttosto vecchio, ma forse mattiast significava 'putStrLn $ id" stack \ n \ noverflow "' che risponde alla domanda. – stites