[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