2012-07-31 15 views
10

Napisałem następujący kod do obsługi polimorficzny drzewo binarne w Haskell jako Preperation dla programowania funkcjonalnego egzaminu w przyszłym tygodniu:Haskell polimorficzne Drzewo Suma

data ITree t = Leaf | Node t (ITree t) (ITree t) 
      deriving (Eq, Ord, Show) 

treeSum :: ITree t -> Int 
treeSum Leaf = 0 
treeSum (Node n t1 t2) = n + (treeSum t1) + (treeSum t2) 

Teraz mam ten problem, że kod nie działa kompilacja:

...\tree.hs:8:26: 
Couldn't match type `t' with `Int' 
    `t' is a rigid type variable bound by 
     the type signature for treeSum :: ITree t -> Int 
     at ...\tree.hs:7:1 
In the first argument of `(+)', namely `n' 
In the first argument of `(+)', namely `n + (treeSum t1)' 
In the expression: n + (treeSum t1) + (treeSum t2) 
Failed, modules loaded: none. 
Prelude> 

Czy wiesz, co jest nie tak z treeSum? Myślę, że ma to coś wspólnego z polimorficznym typem ITree, ale nie wiem, jak rozwiązać ten problem. Czy muszę określić, że typ t musi być typem, który można policzyć/wyliczyć? Prawdopodobnie z instancją klasy tego typu?

Z góry dziękuję za pomoc!

Simon

+4

Czym powinien być "treeSum (Node" marshmellow "Leaf Leaf)"? – dave4420

+0

Nie ma takiej potrzeby :) Ale dla Floats! – saimn

+3

Dobrze, ale typ, który podajesz dla 'treeSum' obiecuje, że działa dla dowolnego typu' t', nawet 'String'. – dave4420

Odpowiedz

11

Kompilator nie może zweryfikować, że wynik będzie Int. W obecnej wersji można wywołać treeSum z argumentem ITree Integer (a operacje nie wygenerowałyby wartości Int).

Spróbuj zmienić sygnaturę na treeSum :: Integral t => ITree t -> t.

+0

Dziękuję, to rozwiązało problem? Co mówi Integral? Czy jest to klasa typu czy konwersja/typowanie? – saimn

+4

'treeSum :: Num t => ITree t -> t' byłoby lepsze: używa tylko' fromInteger' i '(+)'. – dave4420

+2

@saimn To ograniczenie, które mówi, że 't' musi być typem, który implementuje typologię' Integral'. – dave4420

Powiązane problemy