Home > database >  What's wrong with my guard-based haskell code for halving a list?
What's wrong with my guard-based haskell code for halving a list?

Time:12-20

Here is the code:

    listhalve :: [a] -> ([a],[a])
listhalve (x:xs)
    | length [x] == length xs = ([x],xs)
    | length [x] <  length xs = listhalve ([x]    head xs : tail xs)
    | length [x] > length xs = ([x],xs)

There are no error messages when I run or compile it, it just runs forever in the case of non-pair lists.

I'm aware of different ways to write this function that work. I just want to know what's wrong with this code specifically.

Upon taking your comments to heart, I came up with this code here:

listhalve :: [a] -> ([a],[a])
listhalve xs = listhalve' [] xs
    where
        listhalve' :: [a] -> [a] -> ([a],[a])
        listhalve' x y
            | length x == length y = (x, y)
            | length x <  length y = listhalve' (x    (head y)) (tail y)
            | length x >  length y = (x, y)

This gives me an error reading:

test.hs:7:56: error:
    * Occurs check: cannot construct the infinite type: a1 ~ [a1]
    * In the second argument of `(  )', namely `(head y)'
      In the first argument of listhalve', namely `(x    (head y))'
      In the expression: listhalve' (x    (head y)) (tail y)
    * Relevant bindings include
        y :: [a1] (bound at test.hs:5:22)
        x :: [a1] (bound at test.hs:5:20)
        listhalve' :: [a1] -> [a1] -> ([a1], [a1]) (bound at test.hs:5:9)
  |
7 |             | length x <  length y = listhalve' (x    (head y)) (tail y)
  |          

What's the problem with this code?

CodePudding user response:

Consider that listhalve ([x] head xs : tail xs) is the same as listhalve ([x] xs) which is the same as listhalve (x:xs) which is what you went in with, so endless recursion results.

CodePudding user response:

The error is fixed, and the second function works, when you specify head y to be a list, i.e. [head y]. The full, corrected function looks like this:

listhalve :: [a] -> ([a],[a])
listhalve xs = listhalve' [] xs
    where
        listhalve' :: [a] -> [a] -> ([a],[a])
        listhalve' x y
            | length x == length y = (x, y)
            | length x <  length y = listhalve' (x    [head y]) (tail y)
            | length x >  length y = (x, y)
  • Related