2
votes

Quelle est la résolution de cette erreur "Aucune instance"?

J'ai créé un nouveau type décrivant l'arbre binaire

<interactive>:66:13:
No instance for (Num (BinTree a1 -> BinTree a2 -> BinTree a0))
  (maybe you haven't applied enough arguments to a function?)
  arising from the literal ‘5’
In the expression: 5
In the first argument of ‘treehandle’, namely ‘(5 (Null) (Null))’
In the expression: treehandle (5 (Null) (Null))

Et j'ai créé la fonction suivante:

treehandle (5 (Null) (Null))

pour vérifier au moins les valeurs d'entrée .

Quand j'entre la valeur Null, le programme sort le résultat avec succès, mais je ne peux pas entrer l'arbre binaire. J'essaye ainsi:

treehandle :: BinTree a -> Bool
treehandle a = True

mais j'obtiens:

data BinTree a = Null | Num a (BinTree a) (BinTree a)
deriving (Show)

Pourquoi?


0 commentaires

3 Réponses :


12
votes

Vous avez oublié le nom du constructeur de valeur

treehandle (Num 5 (Null) (Null))


4 commentaires

Oui! C'est vrai! Pouvez-vous expliquer pourquoi je dois écrire le nom du constructeur?


Court et doux pour expliquer comment résoudre le problème. L'autre moitié de la question est "comment l'erreur que j'ai obtenue correspond-elle au code que j'ai tapé?". Là, la réponse est que 5 (Null) (Null) est une expression qui essaie d'appliquer la fonction 5 aux arguments (Null) et (Null) - mais 5 n'est pas une fonction.


@AyratArifullin Essayez de vous poser la même question pour l'arborescence vide. Si vous n'avez pas tapé le nom du constructeur, à savoir, Null , que pensez-vous que vous taperiez à la place? (Il y a aussi d'autres bonnes raisons, mais celle-ci devrait vous amener à réfléchir dans la bonne direction.)


En ajoutant à @DanielWagner, imaginez que vous ayez une autre structure composée de deux BinTree, data Bleh a = Bleh a (BinTree a) (BinTree a) .



7
votes

Je trouverais un nom différent pour les constructeurs de données si j'étais vous. Num est également le nom d'une classe de type, cela peut être très déroutant lorsque vous regardez les messages d'erreur.

De plus, dériver Show n'est pas correctement mis en retrait, et vous avez oublié constructeur de données dans treehandle (5 (Null) (Null)) . Voici une version de travail.

data BinTree a = Leaf | Node a (BinTree a) (BinTree a) deriving Show

treehandle :: BinTree a -> Bool
treehandle _ = True

test = treehandle $ Node 5 Leaf Leaf

treehandle veut une valeur de type BinTree a et tout ce que vous lui avez donné était un Int et deux BinTree vides, il a en fait essayé d'appliquer le Int avec les deux BinTree vides et a échoué. Vous devez créer un Node pour obtenir un seul BinTree a que vous pouvez passer à treehandle


0 commentaires

0
votes

Je remercie pour vos réponses. Je vous en suis reconnaissant. Haskell est un langage "sauvage" étant un mélange de Lisp et Prolog. Peu à peu, je commence à m'y habituer. Je partagerais avec mes résultats. Donc, c'est la déclaration de BinTree :

reverse :: BinTree a -> BinTree a
reverse (Val a1 (a2) (a3)) = (Val a1 (reverse a3) (reverse a2))
reverse Leaf = Leaf

Cela ressemble à l'algorithme d'unification Prolog - je veux dire à propos de la définition de "inverse" comme ci-dessous:

data BinTree a = Leaf | Val a (BinTree a) (BinTree a)
 deriving (Show)

Ça marche!


1 commentaires

La fonctionnalité que vous décrivez ici est la correspondance de modèles. Cela ressemble en effet parfois à l'unification et est extrêmement utile pour définir des fonctions simples et lisibles.