Сума на полиморфно дърво на Haskell

Написах следния код за обработка на полиморфно двоично дърво в Haskell като подготовка за изпита по функционално програмиране следващата седмица:

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)

Сега имам проблема, че кодът не се компилира:

...\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>

Знаете ли какво не е наред с treeSum? Мисля, че има нещо общо с полиморфния тип на ITree, но не знам как да реша това. Трябва ли да уточня, че типът t трябва да бъде тип, който може да бъде преброен/изброен? Вероятно с екземпляр на клас от такъв тип клас?

Благодаря ви предварително за помощта!

Саймън


person saimn    schedule 31.07.2012    source източник
comment
Какво трябва да бъде treeSum (Node "marshmellow" Leaf Leaf)?   -  person dave4420    schedule 31.07.2012
comment
Няма нужда от това :) Но за плувки!   -  person saimn    schedule 31.07.2012
comment
Добре, но типът, който давате за treeSum, обещава, че работи за всеки тип t, дори String.   -  person dave4420    schedule 31.07.2012
comment
Просто премахнете сигнатурата на типа за treeSum и след това попитайте компилатора какъв е типът.   -  person augustss    schedule 31.07.2012


Отговори (1)


Компилаторът не може да провери дали резултатът ще бъде Int. Както е сега, можете да извикате treeSum с аргумент ITree Integer (и операциите няма да създадат Int).

Опитайте да промените подписа на treeSum :: Integral t => ITree t -> t.

person jtobin    schedule 31.07.2012
comment
Благодаря ви, това реши ли проблема? Какво казва Integral t? Дали това е клас тип или преобразуване/преобразуване на типове? - person saimn; 31.07.2012
comment
treeSum :: Num t => ITree t -> t би било по-добре: използва само fromIntegerи (+). - person dave4420; 31.07.2012
comment
@saimn Това е ограничение, което казва, че t трябва да бъде тип, който имплементира Integral тип клас. - person dave4420; 31.07.2012