Betr.: [clean-list] Question about internal overloading / type conflict

Paul de Mast demast.pjf at avans.nl
Wed Jun 1 14:16:40 MEST 2005


Hello,

The first error message is a result of:

            | a.tu <> []    = {tl = [y:xs], tu = ys, pu = p + 1}

in function trans1.

You are testing the equality of two lists, so the elements in the list should be testable for equality:

solution 1: extend the typespecification with a typerestriction (a class context):
    trans   :: Int (BiList a) -> (BiList a) | Eq a //  <== 

solution 2: if you only want to test whether a list is empty you can use isEmpty without the above typerestriction. Then the typerestriction is not needed:

change:
            | a.tu <> []    = {tl = [y:xs], tu = ys, pu = p + 1}

to:
            | isEmpty a.tu  = {tl = [y:xs], tu = ys, pu = p + 1}

(Take a look at the implementation of isEmpty to see why you do not compare lists anymore.)


You second error message is due to a restriction of the typechecker.
The reference manual says:

In the specification of a type of a locally defined function one cannot refer to a type variable introduced in the type 
specification of a surrounding function (there is not yet  a  scope  rule on types defined). The programmer can 
therefore not specify the type of such a local function. However, the type will be inferred and checked (after it is 
lifted by the compiler to the global level) by the type system. 

good luck,

Paul de Mast

>>> <clean-list.mail.zooloo at xoxy.net> 31-5-2005 17:35 >>>
Hi,

trying to write a bidirectional lists module for my first useful (well, intended to be) Clean program, I encounter a persistent problem:

For the type class

:: BiList a =  {tl :: [a]    // lower tail (smaller indices)
               ,tu :: [a]    // upper tail (bigger indices)
               ,pu :: Int}   // position (i. e. smallest index) of upper tail


which contains, amongst others,

instance zero (BiList a) where
    zero :: (BiList a)
    zero = {tl = [], tu = [], pu = 0}

mirror   :: Int (BiList a) -> (BiList a)
mirror k a  = {a & tl = a.tu, tu = a.tl, pu = 2*k - a.pu}

I want to define the following auxiliary function: 

trans   :: Int (BiList a) -> (BiList a) 
trans d a=:{tl = xs, tu = [y:ys], pu = p}
    | d >  0    = trans1 (trans (d - 1) a)
    | d == 0    = a
    | d <  0    = trans (~d) (mirror 0 a)
    where
//        trans1 :: (BiList b) -> (BiList b)        // <---- 
        trans1 a
            | a.tu <> []    = {tl = [y:xs], tu = ys, pu = p + 1}
            | otherwise     = zero


This results in 

Overloading error [BiList.icl,131,trans]: internal overloading of "trans1" could not be solved


However, if I specify the type of trans1 by the indicated line, the compiler complains: 

Type error [BiList.icl,137,trans1]:type variable of type of lifted argument a<18276412> appears in the specified type


Supposedly, the latter message would be understandable to me if the type specification of trans1 was 

(BiList a) -> (BiList a)

but I deliberately used b instead of a, so, hmmm ...



Could any decent cleaner give me a hint what I am missing, please?

(Actually, the first message isn't quite clear to me either. It also occurs if I replace zero by the explicite expression.)



Many thanks in advance, 

    zooloo




More information about the clean-list mailing list