簡體   English   中英

Haskell函數返回空列表

[英]Haskell Function Returning Empty List

我真的是Haskell的絕對新手,所以我完全不知道如何調試我寫的一些函數。 當我打電話給shuntingYard ["3+4"]我回來[] ,而我想回來[34+] 任何和所有的幫助將非常非常感謝。

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

作為一般調試技術,您可以使用Debug.Trace模塊找出正在調用的函數以及它們的輸入內容。 使用每個步驟后查看算法的狀態。

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

這打印:

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

嗯,你在第一次通話后失去了一切。 看着__shuntingYard中的警衛,看來“其他”案件被調用了。

也許你想打電話給shuntingYard ["3", "+", "4"]

好的,讓我們來看看當你打電話給shuntingYard ["3+4"]時會發生什么:

  1. 它叫_shuntingYard ["3+4"] []
  2. 它通過_shuntingYard的守衛:
    1. null stmt = null ["3+4"] = false
    2. all isDigit (head stmt) = all isDigit "3+4" = false因為+不是數字
    3. isOperator (head (head stmt)) = isOperator '3' = false
    4. 也錯誤為'3' /= '('
    5. 也錯誤為'3' /= ')'
  3. 由於沒有一個守衛匹配,所以我們進入默認情況並調用_shuntingYard (tail stmt) stack = _shuntingYard [] []
  4. 這次第一個保護( null stmt = null [] )匹配,所以我們調用stackOperations []並獲取[]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM