Ho bisogno di capire come Haskell rappresenta i dati per essere in grado di scrivere buoni programmi Haskell?
-
27-09-2019 - |
Domanda
sto imparando Haskell da un background di Java. Quando ho programma Java, mi sento come se avessi una profonda comprensione di come gli oggetti sono disposti in memoria e le conseguenze di questo. Per esempio io so esattamente come java.lang.String
e il lavoro java.util.LinkedList
e quindi so come io li deve utilizzare. Con Haskell io sono un po 'perso. Per esempio, come funziona (:)
? Dovrei preoccuparmi? E 'specificato da qualche parte?
Soluzione
La risposta breve è no. Durante la programmazione in Haskell si dovrebbe pensare delle vostre strutture dati come oggetti matematici puri e non preoccuparsi di come stanno rappresentati in memoria. La ragione di questo è che, in assenza di effetti collaterali, non c'è davvero nulla di a Dati tranne le funzioni che lo creano e le funzioni che è possibile utilizzare per estrarre le parti più semplici da cui è stato costruito .
Per visualizzare le informazioni relative costruttori di dati come (:)
, o qualsiasi altro termine, utilizzare il comando :type
(o semplicemente :t
in breve) all'interno GHCi:
:Prelude> :type (:)
(:) :: a -> [a] -> [a]
che ti dice che il costruttore (:)
(pronunciato "contro"), assume un valore di qualsiasi tipo, e un elenco dello stesso tipo, e restituisce una lista dello stesso tipo. È inoltre possibile ottenere un po 'più di informazioni utilizzando il comando :info
. Questo ti mostrerà ciò che gli sguardi di definizione dei dati come:
Prelude> :info (:)
data [] a = ... | a : [a] -- Defined in GHC.Types
infixr 5 :
Questo indica che (:)
è il costruttore, che antepone un elemento a un elenco esistente.
Ho anche consigliare vivamente Hoogle non solo per guardare le cose per nome, ma per fare il tipo inverso di ricerca; in cui si conosce la firma della funzione che stai cercando e desidera trovare se qualcuno ha già scritto per voi. Hoogle è bello perché dà descrizioni e esempi di usi.
Forme di induttivo dati
ho detto sopra che non è importante conoscere la rappresentazione dei dati in memoria ... si dovrebbe, tuttavia, capire il forma dei dati si sta trattando, per evitare scarso rendimento decisioni. Tutti i dati in Haskell è definito induttivamente, significa che ha una forma ad albero che si sviluppa sempre verso l'esterno in modo ricorsivo. Si può dire la forma dei dati, cercando in sua definizione; non c'è davvero nulla di nascosto sulle sue caratteristiche prestazionali una volta che sai come leggere questo:
data MyList a = Nil | Cons a (MyList a)
Come si può vedere dalla definizione, l'unico modo è possibile ottenere una nuova MyList
è dal costruttore Cons
. Se si utilizza questo costruttore più volte, vi ritroverete con qualcosa di più o meno di questa forma:
(Cons a5 (Cons a4 (Cons a3 (Cons a2 (Cons a1 Nil)))))
E 'solo un albero senza rami, questa è la definizione di un elenco! E l'unico modo per arrivare a a1
è schioccando fuori ciascuna delle Cons
s a loro volta; quindi accesso all'ultimo elemento è O (n) , mentre l'accesso alla testa è costante di tempo. Una volta che si può fare questo tipo di ragionamento su strutture di dati in base alle loro definizioni, è tutto pronto.
Altri suggerimenti
Breve risposta è "no", non è necessario sapere sui layout di dati -. Una conoscenza di complessità sarà utile se
Per scrivere programmi Haskell altamente ottimizzata, una buona conoscenza della forma delle strutture dati in mucchio di lavoro è essenziale, tuttavia. Uno strumento per aiutare questo è href="http://hackage.haskell.org/package/vacuum-cairo" rel="nofollow noreferrer">, che possono rendere diagrammi delle strutture dati Haskell come sono disposti.
Alcuni esempi:
$ view "hello"
$ view (IntMap.fromList $ zip [1..10] [1..])
Ecco un breve video su come utilizzare lo strumento: http: // www. youtube.com/watch?v=X4-212uMgy8