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?
3 Réponses :
Vous avez oublié le nom du constructeur de valeur
treehandle (Num 5 (Null) (Null))
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)
.
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
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!
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.