[clean-list] Question about uniqueness type error
Jeremy Shaw
jeremy.shaw@lindows.com
Sun, 02 Nov 2003 13:51:59 -0800
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.