exilonX
exilonX

Reputation: 1761

Haskell Instance of Num [Char] required for definition of getPara error

getPara :: (Num [Char])  =>  [Char] -> Integer -> [Char]
getPara "" _ = ""


getPara str nr 
    | (nr == 0 ) && ((head str) == ')' ) = ')' : getPara "" 0 
    | ( nr == 0 ) && ( (head str) == '(' ) = '(' : (getPara (tail str) 0)
    | (nr /= 0 ) && ( (head str) == '(') = (getPara (tail str) nr-1) 
    | (nr == 0 ) && ( (head str) /= '(' ) = (head str) : (getPara (tail str) 0 )
    | otherwise = (getPara (tail str) nr)

What I am trying to do is to get from a String the nr set of brackets and the error I get is:

Illegal Haskell 98 class constraint in type declaration
*** Expression : getPara
*** Type       : Num [Char] => [Char] -> Integer -> [Char]

What is the problem?

Upvotes: 0

Views: 2140

Answers (2)

Landei
Landei

Reputation: 54584

Starting from Matt's answer, let's beautify the code (I didn't check if it works, though). First of all pattern matching for lists is much nicer than lots of head and tail:

getPara :: [Char] -> Integer -> [Char]
getPara "" _ = ""
getPara (x:xs) nr 
    | (nr == 0 ) && ( x == ')' )  = ')' : getPara "" 0 
    | (nr == 0 ) && ( x == '(' ) = '(' : getPara xs 0
    | (nr /= 0 ) && ( x == '(' )  =  getPara xs (nr-1)  -- here!
    | (nr == 0 ) && ( x /= '(' ) = x : getPara xs 0 
    | otherwise = getPara xs nr

Now you can pattern match even more:

getPara :: [Char] -> Integer -> [Char]
getPara "" _ = ""
getPara (')':xs) 0                 = ')' : getPara "" 0 
getPara ('(':xs) 0                 = '(' : getPara xs 0
getPara ('(':xs) nr   | nr /= 0    = getPara xs (nr-1)  -- here!
getPara (x:xs) 0      | x /= '('   = x : getPara xs 0 
getPara (_:xs) nr                  = getPara xs nr

[Edit]

As Daniel pointed out, a careful analysis would reveal that the remaining guards are always true.

getPara :: [Char] -> Integer -> [Char]
getPara "" _ = ""
getPara (')':xs) 0   = ')' : getPara "" 0 
getPara ('(':xs) 0   = '(' : getPara xs 0
getPara ('(':xs) nr  = getPara xs (nr-1)  -- here!
getPara (x:xs) 0     = x : getPara xs 0 
getPara (_:xs) nr    = getPara xs nr

Upvotes: 2

Matt Fenwick
Matt Fenwick

Reputation: 49105

Your type signature for getPara is not allowed, but the underlying problem is that you're missing parentheses somewhere deep in the definition. If your change your code to:

getPara :: [Char] -> Integer -> [Char]
getPara "" _ = ""

getPara str nr 
    | (nr == 0 ) && ((head str) == ')' )  = ')' : getPara "" 0 
    | (nr == 0 ) && ( (head str) == '(' ) = '(' : (getPara (tail str) 0)
    | (nr /= 0 ) && ( (head str) == '(')  = (getPara (tail str) (nr-1))  -- here!
    | (nr == 0 ) && ( (head str) /= '(' ) = (head str) : (getPara (tail str) 0 )
    | otherwise = (getPara (tail str) nr)

it compiles ... but I'm not sure if it works.

There were two changes:

  1. type signature of getPara
  2. surround nr-1 in parentheses in

    | (nr /= 0 ) && ( (head str) == '(')  = (getPara (tail str) (nr-1))
    

Upvotes: 2

Related Questions