函数应用于太多参数错误

Ale*_*lex 0 haskell

当我尝试编译以下代码时:

matcHelp :: String -> Stack Char -> Stack Char
matcHelp b = mtHelp b (MakeS([])) (MakeS([])) where 
                      mtHelp b result1 result2 =
                          if (b == [])
                              then result1 result2
                          else if head b == '('
                              then mtHelp (tail b) (push '(' result1) (result2)
                          else if head b == '['
                              then mtHelp (tail b) (result1) (push '[' result2)
                          else if (head b == ')')
                              then mtHelp (tail b) (popOut result1) (result2)
                          else if (head b == ']')
                              then mtHelp (tail b) (result1) (popOut result2)
                          else mtHelp (tail b) (result1) (result2)
Run Code Online (Sandbox Code Playgroud)

我得到了函数push:

push :: a -> Stack a -> Stack a
push x (MakeS(xs)) = MakeS(x:xs)
Run Code Online (Sandbox Code Playgroud)

应用于太多参数,特别是在实例中(push '(' result1).我不明白为什么?

我得到的实际错误是:

Couldn't match expected type `t1 -> t0' with actual type `Stack a0'
    In the return type of a call of `push'
    Probable cause: `push' is applied to too many arguments
    In the second argument of `mtHelp', namely `(push '(' result1)'
    In the expression: mtHelp (tail b) (push '(' result1) (result2)
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)

注意:MakeS是一个数据构造函数

newtype Stack a = MakeS([a]) deriving Show
Run Code Online (Sandbox Code Playgroud)

cdk*_*cdk 5

问题是这条线

if (b == []) then result1 result2
Run Code Online (Sandbox Code Playgroud)

implies result1是一个要应用的函数result2.从您的类型签名,matchHelp应该返回a Stack Char,所以你在这里犯了一个错误.

从您的评论中可以清楚地看到,您希望从中返回多个值matchHelp.在Haskell中,所有函数都接受一个参数并始终返回一个结果.甚至像一个功能

(+) :: Int -> Int -> Int
Run Code Online (Sandbox Code Playgroud)

取一个参数(an Int)并返回一个结果(一个函数Int -> Int).您可以像这样编写类型签名:

(+) :: Int -> (Int -> Int)
Run Code Online (Sandbox Code Playgroud)

但无论如何,Haskell会为你做这件事.这被称为"currying".

Haskell返回多个值的方法是返回包含这些值的单个元组或您自己定义的数据结构.

无关,你的功能是不是很"哈斯克尔-Y"与所有这些if .. then .. else,并head/tail在模式匹配和守卫应改为使用.这是在元组中具有多个返回值的重写函数.

matchHelp :: String -> Stack Char -> (Stack Char, Stack Char)
matchHelp b = mtHelp b (MakeS []) (MakeS [])
    where mtHelp []     result1 result2 = (result1, result2)
          mtHelp (x:xs) result1 result2     
            | x == '('  = mtHelp xs (push '(' result1) (result2)
            | x == '['  = mtHelp xs (result1) (push '[' result2)
            | x == ')'  = mtHelp xs (popOut result1) (result2) 
            | x == ']'  = mtHelp xs (result1) (popOut result2)
            | otherwise = mtHelp xs result1 result2 
Run Code Online (Sandbox Code Playgroud)