[Haskell-cafe] Type-level programming problem
oleg at pobox.com
oleg at pobox.com
Tue May 1 00:12:07 EDT 2007
Thomas Schilling wrote:
> data T
> class Foo ns a b c | ns -> a, ns -> b, ns -> c where
> mkFoo :: ns
> defaultA :: a
> defaultB :: c -> IO b
> defaultC :: [T] -> c
> f :: c -> b -> a -> (b, Int)
> data DefaultA
> instance Foo ns a b c => Apply DefaultA ns a where
> apply _ _ = defaultA
>
> but I get:
>
> Could not deduce (Foo ns1 a b1 c1)
> from the context (Apply MakeAs ns a, Foo ns a b c)
> arising from use of `defaultA'
Indeed. Let us examine the inferred type of defaultA:
*Main> :t defaultA
defaultA :: (Foo ns a b c) => a
We see it is a value polymorphic over four type variables: ns, a, b,
and c. The type variable 'a' is also the type of the value, so we have
a way to instantiate it. There is no direct way to instantiate the
remaining three. If there were a functional dependency a -> ns, a->b,
a->c, we could have instantiated the remaining variables. But there
are no such dependencies. So, there is really no way we can
ever instantiate the type variables ns, b and c -- and so the typechecker
will complain.
So, we need either a functional dependency a -> ns in the definition
of Foo, or defaultA should have a signature defaultA :: ns -> a
(and ditto for other defaults). As I understand, the function
'defaultA' can be present in different components, identified by
ns. When we write 'defaultA' however, how can we say that we mean
defaultA of component X rather than of component Y? There isn't any
way to name the desired component...
Incidentally, if we represent components by records
data XRec = XRec { defaultA :: XA }
then the type of defaultA is Xref -> XA. It is the function from the
type of the `namespace'. This seems to suggest the
signature of defaultA should be ns -> a ...
BTW, there are other ways to add the name of the namespace to the
signature of defaultA. For example:
newtype TaggedT ns a = TaggedT a
class Foo ns a b c | ...
defaultA :: TaggedT ns a
or
class Foo ns a b c | ...
defaultA :: ns a
etc.
More information about the Haskell-Cafe
mailing list