Dimitar
Dimitar

Reputation: 4801

Error while getting the middle element of a list in Haskell

First, I am completely new to Haskell, so sorry for the question in advance, as it might look kind of simple, but still I get this error message:

Couldn't match expected type `[a]' with actual type `a'
  `a' is a rigid type variable bound by
      the type signature for middle :: [a] -> a
      at myFile.lhs:18:12
Relevant bindings include
  xs :: [a] (bound at myFile.lhs:20:12)
  x :: a (bound at myFile.lhs:20:10)
  middle :: [a] -> a
    (bound at myFile.lhs:19:2)
In the first argument of `(!!)', namely `x'
In the first argument of `div', namely `x !! length xs'

Failed, modules loaded: none.

While trying to load:

>middle :: [a] -> a
>middle [] = []
>middle (x:xs) = if (l `mod` 2 == 0) then xs !! (l`div` 2) - 1 else x !! l `div` 2
    where l = length xs

If something is vague or unclear, please comment.

EDIT Because of the use of div I get:

Error:     No instance for (Integral a) arising from a use of `div'
Possible fix:
  add (Integral a) to the context of
    the type signature for middle :: [a] -> a
In the expression: xs !! l `div` 2
In the expression:
  if (l `mod` 2 == 0) then xs !! (l `div` 2) - 1 else xs !! l `div` 2
In an equation for `middle':
    middle (x : xs)
      = if (l `mod` 2 == 0) then
            xs !! (l `div` 2) - 1
        else
            xs !! l `div` 2
      where
          l = length xs

Upvotes: 1

Views: 499

Answers (1)

chi
chi

Reputation: 116174

Note that x is just an element, not a list. So, using x !! anything is a type error. Did you mean xs !! anything instead?

Further,

middle [] = []

is wrong since you must return an element, not a list. Since there is no middle element, we can only return bottom, e.g.

middle [] = error "middle: empty list"

The above makes the function a partial one, i.e. if in a larger program you call the function with an empty list, the program will crash.

If you want to forbid that, you can change the type to Maybe:

middle :: [a] -> Maybe a
middle []     = Nothing
middle (x:xs) = Just (.....)

Upvotes: 1

Related Questions