简体   繁体   English

Haskell函数返回空列表

[英]Haskell Function Returning Empty List

I'm really an absolute newbie at Haskell, so I'm at a total loss as to how to debug some functions I wrote. 我真的是Haskell的绝对新手,所以我完全不知道如何调试我写的一些函数。 When I call shuntingYard ["3+4"] I get back [] , whereas I want to get back [34+] . 当我打电话给shuntingYard ["3+4"]我回来[] ,而我想回来[34+] Any and all help would be greatly, greatly appreciated. 任何和所有的帮助将非常非常感谢。

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 []

As a general debugging technique, you can use the Debug.Trace module to find out which functions are being called and what their inputs are. 作为一般调试技术,您可以使用Debug.Trace模块找出正在调用的函数以及它们的输入内容。 Using look at the state of your algorithm after each step. 使用每个步骤后查看算法的状态。

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 -}

This prints: 这打印:

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

Hmm, you lost everything after the first call. 嗯,你在第一次通话后失去了一切。 Looking at the guards in __shuntingYard, it seems that the "otherwise" case gets called. 看着__shuntingYard中的警卫,看来“其他”案件被调用了。

Maybe you wanted to call shuntingYard ["3", "+", "4"] ? 也许你想打电话给shuntingYard ["3", "+", "4"]

Ok, let's just play through what happens when you call shuntingYard ["3+4"] : 好的,让我们来看看当你打电话给shuntingYard ["3+4"]时会发生什么:

  1. It calls _shuntingYard ["3+4"] [] 它叫_shuntingYard ["3+4"] []
  2. It goes through the guards of _shuntingYard : 它通过_shuntingYard的守卫:
    1. null stmt = null ["3+4"] = false
    2. all isDigit (head stmt) = all isDigit "3+4" = false as + is not a digit all isDigit (head stmt) = all isDigit "3+4" = false因为+不是数字
    3. isOperator (head (head stmt)) = isOperator '3' = false
    4. Also false as '3' /= '(' 也错误为'3' /= '('
    5. Also false as '3' /= ')' 也错误为'3' /= ')'
  3. Since none of the guards matched, so we go into the default case and call _shuntingYard (tail stmt) stack = _shuntingYard [] [] 由于没有一个守卫匹配,所以我们进入默认情况并调用_shuntingYard (tail stmt) stack = _shuntingYard [] []
  4. This time the first guard( null stmt = null [] ) matches, so we call stackOperations [] and get [] . 这次第一个保护( null stmt = null [] )匹配,所以我们调用stackOperations []并获取[]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM