pioupiou1211
pioupiou1211

Reputation: 373

Couldn't match expected type Haskell

I need to make a list of case like [B,N,N] with a list that contain the index of the Nlike [1,2] here, and an int that represent the length of the final list.

Here's my program:

lignebn :: Int -> [Int] -> [Case]
lignebn i [] = []
lignebn i x 
    | i == last x = [N] : lignebn (i-1) init x -- line 101
    | otherwise = [B] : lignebn (i-1) init x

Here are the errors:

devoir.hs:101:17:
    Couldn't match expected type ‘[Int]’ with actual type ‘Int’
    In the first argument of ‘last’, namely ‘(x)’
    In the second argument of ‘(==)’, namely ‘last (x)’

devoir.hs:101:29:
    Couldn't match expected type ‘Int -> [Case]’
                with actual type ‘[Case]’
    The function ‘lignebn’ is applied to three arguments,
    but its type ‘Int -> [Int] -> [Case]’ has only two
    In the second argument of ‘(++)’, namely ‘lignebn (i - 1) init (x)’
    In the expression: [N] ++ lignebn (i - 1) init (x)

devoir.hs:101:43:
    Couldn't match expected type ‘[Int]’
                with actual type ‘[a0] -> [a0]’
    Probable cause: ‘init’ is applied to too few arguments
    In the second argument of ‘lignebn’, namely ‘init’
    In the second argument of ‘(++)’, namely ‘lignebn (i - 1) init (x)’

devoir.hs:102:26:
    Couldn't match expected type ‘Int -> [Case]’
                with actual type ‘[Case]’
    The function ‘lignebn’ is applied to three arguments,
    but its type ‘Int -> [Int] -> [Case]’ has only two
    In the second argument of ‘(++)’, namely ‘lignebn (i - 1) init (x)’
    In the expression: [B] ++ lignebn (i - 1) init (x)

devoir.hs:102:40:
    Couldn't match expected type ‘[Int]’
                with actual type ‘[a1] -> [a1]’
    Probable cause: ‘init’ is applied to too few arguments
    In the second argument of ‘lignebn’, namely ‘init’
    In the second argument of ‘(++)’, namely ‘lignebn (i - 1) init (x)’
Failed, modules loaded: none.

I don't understand what's going on, the code seems ok to me...

Upvotes: 0

Views: 1543

Answers (2)

dfeuer
dfeuer

Reputation: 48580

In your recursive calls you need parentheses around init x. As it is, you are passing the init function and x. You probably also want a list of N and B rather than a list of lists of them, but it's hard to say for sure since you don't include the definition of your Case type.

lignebn :: Int -> [Int] -> [Case]
lignebn i [] = []
lignebn i x 
    | i == last x = N : lignebn (i-1) (init x) -- line 101
    | otherwise = B : lignebn (i-1) (init x)

Note also that partial functions like last are widely discouraged. Better would be something like this (untested):

unsnoc :: [a] -> Maybe ([a], a)
unsnoc [] = Nothing
unsnoc (x : xs) = Just ps where
   ps = case unsnoc xs of
          Nothing -> ([], x)
          Just (~(ys, y)) -> Just (x : ys, y)

Upvotes: 1

jamshidh
jamshidh

Reputation: 12060

last expects a list, but you have defined it in the pattern match as and Int

lignebn :: Int -> [Int] -> [Case]
lignebn i (x:xs) = ....

implies that

(x:xs)::[Int]

which implies that x is an Int.


On an unrelated note, in Haskell you do not need to put parens around function calls. Don't call last like this last(x), instead use last x. It will work, but isn't idiomatic Haskell.

Upvotes: 1

Related Questions