Question

Je suis vraiment un débutant absolu à Haskell, donc je suis à une perte totale quant à la façon de déboguer des fonctions que j'ai écrit. Quand j'appelle shuntingYard ["3+4"] je reçois [] dos, alors que je veux revenir [34+]. Toute aide serait grandement, grandement appréciée.

import Char

isOperator :: Char -> Bool
isOperator x = elem x ['+','-','*','/','%','^','!','=','<','>']

associativityOf :: Char -> String
associativityOf x = if elem x ['+','-','*','/','%']
                    then "Left"
                    else "Right"

precedenceOf :: Char -> Int
precedenceOf x
    | elem x "=<>"   = 1 
    | elem x "+-"    = 2
    | elem x "*/%"   = 3
    | elem x "^!"    = 4
    | otherwise      = 0

operatorActions :: [[Char]] -> [[Char]] -> [[Char]]
operatorActions stmt stack
    | ( tokenAssoc == "Left"  && tokenPrecedence <= stackPrecedence ) ||        
      ( tokenAssoc == "Right" && tokenPrecedence <  stackPrecedence ) =
        [stackOper] : _shuntingYard stmt (tail stack)
    | otherwise   = _shuntingYard (tail stmt) ((head stmt) : stack)
    where tokenAssoc       = associativityOf (head (head stmt))
          tokenPrecedence  = precedenceOf    (head (head stmt))
          stackOper        = if (not (null stack))
                           then (head (head stack))
                           else '='
          stackPrecedence  = precedenceOf stackOper

stackOperations :: [[Char]] -> [[Char]]                                
stackOperations stack
    | ((not (null stack)) && (head (head stack)) == '(') = 
      error "Unbalanced parens."
    | null stack = []
    | otherwise  = (head stack) : _shuntingYard [] (tail stack)

_shuntingYard :: [[Char]] -> [[Char]] -> [[Char]]
_shuntingYard stmt stack
    | null stmt          = stackOperations stack
    | all isDigit (head stmt) = (head stmt) : _shuntingYard (tail stmt) stack
    | isOperator  (head (head stmt)) = operatorActions stmt stack
    | (head (head stmt)) == '('=
      _shuntingYard (tail stmt) ((head stmt) : stack)
    | (head (head stmt)) == ')' = if (head (head stack)) == '('
                            then _shuntingYard (tail stmt) (tail stack)
                            else (head stack) : _shuntingYard stmt (tail stack)
    | otherwise = _shuntingYard (tail stmt) stack

shuntingYard :: [[Char]] -> [[Char]]
shuntingYard stmt = _shuntingYard stmt []
Était-ce utile?

La solution

En tant que technique de débogage générale, vous pouvez utiliser le module Debug.Trace pour savoir quelles fonctions sont appelées et quelles sont leurs entrées sont. En utilisant regard sur l'état de votre algorithme après chaque étape.

import Debug.Trace

-- Show arguments each time _shuntingYard is called
_shuntingYard :: [[Char]] -> [[Char]] -> [[Char]]
_shuntingYard stmt stack = traceShow (stmt, stack) $ __shuntingYard stmt stack

__shuntingYard stmt stack
  | null stmt = stackOperations stack
  {- etcetera -}

Cette impression:

(["3+4"],[])
([],[])

Hmm, vous avez tout perdu après le premier appel. En regardant les gardes __shuntingYard, il semble que le cas « autrement » est appelé.

Peut-être que vous vouliez appeler shuntingYard ["3", "+", "4"]?

Autres conseils

Ok, let's just play through what happens when you call shuntingYard ["3+4"]:

  1. It calls _shuntingYard ["3+4"] []
  2. It goes through the guards of _shuntingYard:
    1. null stmt = null ["3+4"] = false
    2. all isDigit (head stmt) = all isDigit "3+4" = false as + is not a digit
    3. isOperator (head (head stmt)) = isOperator '3' = false
    4. Also false as '3' /= '('
    5. Also false as '3' /= ')'
  3. Since none of the guards matched, so we go into the default case and call _shuntingYard (tail stmt) stack = _shuntingYard [] []
  4. This time the first guard(null stmt = null []) matches, so we call stackOperations [] and get [].
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top