2017-05-03 1 views
1

J'ai des problèmes avec (je suppose) les types avec lesquels je travaille (pour une affectation sur le codage de Huffman) dans ma déclaration de cas. Je veux travailler depuis le haut de l'arbre jusqu'à chaque feuille et retourner une liste de paires de valeurs clés. [] passe bien, mais [h] renvoie une erreur d'analyse et je ne sais pas pourquoi.Haskell: Erreur d'analyse dans une instruction de cas (impliquant des listes!)

type HCode = [Bit] 
data Bit = L | R deriving (Eq, Show) 
data Tree a = Leaf Int a | Node Int (Tree a) (Tree a) deriving (Eq) 

convert :: Ord a => HCode -> Tree a -> [(a,HCode)] 
convert hs tree = 
    case hs tree of 
    []  (Node _ a b) -> (convert [L]   a)++(convert [R]   b) 
    [h] (Node _ a b) -> (convert !([h]++[L]) a)++(convert !([h]++[R]) b) 
    (h:hs) (Node _ a b) -> (convert !((h:hs)++[L]) a)++(convert !((h:hs)++[R]) b) 
    [h] (Leaf _ a) -> [(a, [h])] 
    (h:hs) (Leaf _ a) -> [(a, (h:hs))] 

Aussi, je n'ai pas utilisé de frange avant mais je pense qu'ils sont appropriés ici? Auraient-ils un impact sur la performance? Est-ce que je les utilise même dans le bon contexte?

+0

Je vous suggère de demander une autre question au sujet des modèles bang. Une question - par question de stackoverflow est la meilleure. En bref: Non, vous ne les utilisez pas correctement. –

+0

Les bangs n'ont pas beaucoup de sens pour moi ici, mais je peux me tromper. Dans les deux cas, je pense que c'est une question distincte du problème d'appariement de modèles que vous avez. – amalloy

+0

@ ThomasM.DuBuisson ouais était seulement une question secondaire mineure, un oui ou non était tout ce que je cherchais, donc merci – 420fedoras

Répondre

3

case a b of ... ne correspond pas à la fois contre a et b, mais correspond plutôt sur le résultat de l'appel a en fonction, avec l'argument b. Une expression case correspond toujours exactement à une valeur, et même la première clause (qui selon vous fonctionne) ne fonctionne absolument pas.

Pour match contre deux valeurs, vous les envelopper dans un tuple, et puis se briser le tuple dans chaque clause, comme suit:

case (hs, tree) of 
    ([], (Node _ a b)) -> ... 
    ([h], (Node _ a b)) -> ... 
    ... 
+0

Je vois, cela a du sens. Dans ce cas, pourquoi le compilateur ne me donne pas une erreur d'analyse pour la première ligne? – 420fedoras

+1

@ 420fedoras Je pense que c'est une chose de phase. En jouant un peu dans ghci, il semble que '[] x' * fait * analyser comme un pattern (même chose que' Just x'), puisque '[]' est considéré comme un constructeur. Puis, plus tard, lors de la vérification typographique, il se plaint que [] 'a reçu trop d'arguments. – luqui