[Haskell-cafe] Is this related to monomorphism restriction?
wren ng thornton
wren at freegeek.org
Tue Dec 23 20:34:42 EST 2008
Maurício wrote:
> Hi,
>
> Why isn't the last line of this code allowed?
>
> f :: (TestClass a) => a -> Integer
> f = const 1
> a = (f,f)
> g = fst a
Just to make explicit what other folks have brought up in passing. The
real type of @f@ (that is without syntactic sugar) is:
> f :: forall a. TestClass a => a -> Integer
Which in turn means that the type for @a@ is:
> a :: ( (forall a. TestClass a => a -> Integer)
> , (forall a. TestClass a => a -> Integer) )
This signature isn't valid Haskell98 since it embeds the quantification
and the contexts, but it's easily transformable into valid syntax.
== {alpha conversion}
> a :: ( (forall a. TestClass a => a -> Integer)
> , (forall b. TestClass b => b -> Integer) )
== {scope extension, twice}
> a :: forall a b. ( (TestClass a => a -> Integer)
> , (TestClass b => b -> Integer) )
== {context raising, twice}
> a :: forall a b. (TestClass a, TestClass b) => ( (a -> Integer)
> , (b -> Integer) )
== {invisible quantification sugar (optional)}
> a :: (TestClass a, TestClass b) => ( (a -> Integer)
> , (b -> Integer) )
The alpha conversion, necessary before doing scope extension, is the
step that might not have been apparent. Because @f@ is polymorphic in
its argument, the different instances of @f@ can be polymorphic in
different ways. This in turn is what leads to the ambiguity in @g@,
monomorphism restriction aside.
If you wanted to have @a@ give the same types to both elements of the
tuple, then you can use this expression instead:
> a' = let f' = f in (f',f')
The important difference is that we're making the sharing explicit. This
in turn means that, while @fst a'@ and @snd a'@ are still polymorphic,
they can only be polymorphic in the same way. Hence,
> a' :: forall a. TestClass a => ( (a -> Integer)
> , (a -> Integer) )
This transformation is only looking at the type-variable sharing issue.
It still runs afoul of the monomorphism restriction unless you resolve
it in the ways others have mentioned.
--
Live well,
~wren
More information about the Haskell-Cafe
mailing list