[clean-list] Question about uniqueness type error

Arjen van Weelden arjenw@cs.kun.nl
Mon, 03 Nov 2003 09:49:43 +0100


Hi,

Attributing the synonym types with '*', instead of '.', also works.
This states that these types must always be unique, which does not look 
like a problem in your example.

:: *MonoFrames a  :== *{#a}
:: *StereoFrames a :== *(*{#a}, *{#a})

:: *Stream a 	= MonoStream *(MonoFrames a)
		| StereoStream *(StereoFrames a)

Could be a compiler bug, if it cannot deduce uniqueness when you use 
type synonyms with '.', and it can if you use '*' or no type synonyms.

On another hand, type synonyms do not always do what you think they 
should do. Especially when using classes and/or uniqueness attributes.

kind regards,
	Arjen

Jeremy Shaw wrote:

> Hello,
> 
> I am getting a uniqueness error I can not explain when I try to
> combine type synonyms and classes. I can't figure out if I am
> misunderstanding something, or if it is a compiler bug.
> 
> The following code is based on some actually code I wrote, but with
> all the irrelevant stuff stripped out for readability.
> 
> ----->
> 
> module test
> 
> import StdEnv
> 
> :: MonoFrames a  :== .{#a}
> :: StereoFrames a :== .(.{#a},.{#a})
> 
> :: Stream a 	= MonoStream .(MonoFrames a)
> 		| StereoStream .(StereoFrames a)
> 
> class Frames a where
>     mixInFrames :: *a *a -> *a
> 
> instance Frames (MonoFrames *Int) where
>     mixInFrames :: *(MonoFrames *Int) *(MonoFrames *Int) -> *(MonoFrames *Int)
>     mixInFrames frames1 frames2 = frames2
> 
> // This variation does not work
> instance Frames (StereoFrames *Int) where
>     mixInFrames :: *(StereoFrames *Int) *(StereoFrames *Int) -> *(StereoFrames *Int)
>     mixInFrames (f1l, f1r) (f2l, f2r) = (f2l, f2r)
> 
> /*
> // This one works
> instance Frames (*{#*Int},*{#*Int}) where
>     mixInFrames :: *(*{#*Int},*{#*Int}) *(*{#*Int},*{#*Int}) -> *(*{#*Int},*{#*Int})
>     mixInFrames (f1l, f1r) (f2l, f2r) = (f2l, f2r)
> */
> 
> // so does this 
> mixInFrames2 :: *(StereoFrames *Int) *(StereoFrames *Int) -> *(StereoFrames *Int)
> mixInFrames2 (f1l, f1r) (f2l, f2r) = (f2l, f2r)
> 
> 
> mixInStream :: *(Stream *Int) *(Stream *Int) -> *(Stream *Int)
> mixInStream (MonoStream frames1)   (MonoStream frames2)   = (MonoStream   (mixInFrames frames1 frames2))
> mixInStream (StereoStream frames1) (StereoStream frames2) = (StereoStream (mixInFrames frames1 frames2))
> 
> Start = "Hello, World!"
> 
> <-----
> 
> If I try to compile the code as shown, I get the following error:
> 
> clm test -o test
> Compiling test
> Uniqueness error [test.icl,36,mixInStream]:"argument 1 of StereoStream" attribute at indicated position could not be coerced *(^ {#*Int},{#*Int})
> Uniqueness error [test.icl,36,mixInStream]:"argument 2 of mixInFrames" attribute at indicated position could not be coerced *(StereoFrames ^ *Int)
> Uniqueness error [test.icl,36,mixInStream]:"argument 1 of mixInFrames" attribute at indicated position could not be coerced *(StereoFrames ^ *Int)
> make: *** [test] Error 1
> 
> If I comment out this instance:
> instance Frames (StereoFrames *Int)
> 
> And uncomment this instance:
> instance Frames (*{#*Int},*{#*Int})
> 
> The code compiles without any errors. OR, if I change mixInStream to
> call mixInFrames2, it also compiles fine.
> 
> So I am confused. 
> 
> How come mixInFrames2 works, but the 'instance Frames
> (StereoFrames *Int)' gives a uniqueness error.
>  
> Am I correct in thinking that:
> 
> mixInFrames :: *(StereoFrames *Int) *(StereoFrames *Int) -> *(StereoFrames *Int)
> 
> is a type synonym for:
> 
> mixInFrames :: *(*{#*Int},*{#*Int}) *(*{#*Int},*{#*Int}) -> *(*{#*Int},*{#*Int})
> 
> Thanks.
> Jeremy Shaw.
> 
> ps. I tested this with clean 2.1 for linux.
> 
> 
> _______________________________________________
> clean-list mailing list
> clean-list@cs.kun.nl
> http://www.cs.kun.nl/mailman/listinfo/clean-list