2010-08-28 12 views
17

sto attraversando i problemi del libro O'Reilly Haskell. Il problema su cui sto lavorando èCominciando Haskell - ottenendo "non nel campo di applicazione: i dati del costruttore" Errore

Using the binary tree type that we defined earlier in this chapter, 
write a function that will determine the height of the tree. The height 
is the largest number of hops from the root to an Empty. For example, the 
tree Empty has height zero; Node "x" Empty Empty has height one; 
Node "x" Empty (Node "y" Empty Empty) has height two; and so on. 

Sto scrivendo il mio codice in un file chiamato ch3.hs. Ecco il mio codice:

36 data Tree a = Node a (Tree a) (Tree a) 
37    | Empty 
38    deriving (Show) 
39 
40 --problem 9:Determine the height of a tree 
41 height :: Tree -> Int 
42 height (Tree node left right) = if (left == Empty && right == Empty) then 0 else max (height left) (height right) 

apertura ghci nel terminale e digitando: ch3.hs. carico Quando faccio che ottengo il seguente errore:

Prelude> :load ch3.hs 
[1 of 1] Compiling Main    (ch3.hs, interpreted) 

ch3.hs:42:7: Not in scope: data constructor `Tree' 
Failed, modules loaded: none. 

mi aspetto che il costruttore di dati Albero dovrebbe essere lì, perché ho definito nelle righe sopra il metodo di altezza. Ma quando provo a caricare il file, mi viene detto che il costruttore di dati non è in ambito. Apprezzo il tuo aiuto e la spiegazione del motivo per cui si verifica questo errore. Grazie, Kevin

risposta

21

Change

height (Tree node left right) 

a

height (Node node left right) 

Ciò significa che il pattern matching lavori sui costruttori della algebraic data type (ADT). Tree non è un costruttore, è il nome dell'ADT.

Btw, è necessario commentare la sua dichiarazione firma funzione per compilare il codice perché contiene un errore.

È quindi possibile verificare il tipo derivato tramite

 
:t height 

in ghci o hugs.

+1

Grazie, ha funzionato. Non riesco ancora a comprendere appieno cosa sta succedendo e ora sto riscontrando errori in fase di esecuzione, ma continuerò a fissare, pensare e fare il debug. –

+3

Un altro esempio potrebbe renderlo più facile da capire. Facciamo finta che stiamo lavorando con numeri interi, non con alberi. Int è il nome del tipo intero. Non puoi aggiungere "Int + Int" perché Int è il nome del tipo, non un costruttore che restituisce un valore di quel tipo. Cose come 0, 1, 2, ... sono i costruttori, e se vuoi lavorare con i numeri interi, è così che li inserisci nel tuo programma. Applicando questo al tuo caso, 'Tree' è il nome del tipo, e' Node' (o 'Empty') è come ottieni un valore * di * quel tipo. – jrockway

+0

HaskellWiki ha anche una sezione utile, e utilizza anche Tree come esempio: http://www.haskell.org/haskellwiki/Constructor – jrockway

2

È pattern-match contro costruttori, vale a dire i casi , del vostro Tree ADT. Tree è proprio ciò che li riassume tutti.

E 'molto più semplice come questo, e, la maggior parte di tutti, corretta:

height Empty = 0 
height (Node _ l r) = 1 + max (height l) (height r) 
+2

-1 Questo è sbagliato. Test con altezza (Nodo 1 (Nodo 2 vuoto vuoto) (Nodo 3 vuoto vuoto)) '. Dovrebbe essere 2, è 0 - è 0 per ogni input, a causa dello stesso bug che l'OP ha. – delnan

+0

Grazie. Sto ancora cercando di abituarmi alla corrispondenza degli schemi. Ho contrassegnato l'altra risposta corretta perché la domanda riguardava il costruttore di dati, ma anche questo è utile. –

+0

Risolto - è necessario aggiungere 1 al valore di max (altezza a sinistra) (altezza a destra) in modo che non continui a restituire 0. –

6

Il codice è sbagliato, su più livelli. Sembra che tu abbia frainteso i tipi di dati algebrici.

  • La firma tipo è sbagliato, un Tree è sempre una Tree di un tipo specifico - cui è stato chiamato a nella sua dichiarazione, e che può essere di qualsiasi tipo (dal momento che non ha vincolo di esso). Quindi, heigth deve prendere un Tree di un certo tipo - uno Tree SomeType, anche. È possibile e dovrebbe utilizzare il tipo più generico per SomeType, ad esempio una variabile di tipo a.
  • Quando pattern matching, è il nome di una specifica costruttore - Node a (Tree a) (Tree a) o Empty - per abbinare contro, non contro il tipo nel suo complesso.Quindi height (Node ...) corrisponderebbe a Node, height (Empty) corrisponderebbe a Empty e height (Tree ...) proverebbero a corrispondere a un costruttore denominato Tree, ma non ce n'è. Questo è il messaggio di errore che ricevi.
  • Mai e poi mai confrontare (via ==) con un Costruttore. Funzionerebbe davvero se tu scrivessi deriving (Show, Eq). Tuttavia, dovresti utilizzare la corrispondenza dei modelli per determinare se hai raggiunto uno Empty
  • Quale conduce a: Stai solo corrispondendo a Node, non a Empty - devi aggiungere una clausola per Empty.
  • Inoltre, la funzione restituisce sempre 0 per tutti gli input se si risolvono tutti i problemi precedenti. Non si restituisce mai nulla tranne lo 0 o il massimo del numero di telefono height - che può, a sua volta, restituire solo 0 o il massimo dei rispettivi numeri di telefono 'height, ecc. All'infinito. È necessario aumentare il risultato ad ogni livello;)
+1

Grazie per l'aiuto. Ho appena iniziato e mi sto ancora abituando alla nuova lingua. –

Problemi correlati