[Haskell-cafe] Polyvariadic composition

Ryan Ingram ryani.spam at gmail.com
Tue Jul 31 02:23:30 CEST 2012


My completely off-the-cuff guess is that
    a a b b
isn't considered more or less specific than
    (x -> a) ar (x -> b) br
since they both apply some constraint on the types.  For example, it's not
immediately clear that the first instance can't be used for (x -> a) (x ->
a) (x -> b) (x -> b)

Whereas when you say
    a ar b br
the type
    (x -> a) ar (x -> b) br
is strictly more specific, so the overlapping instance can be chosen.

Remember instance selection is done entirely via the instance head, so
    instance X a a
is not the same as
    instance (a ~ b) => X a b

The first case supplies an instance for any two equal types, and the second
case supplies an instance for *any two types*, then throws an error if the
compiler can't prove that the two types are equal.

For example, without overlapping instances, you can write

    class X a b where foo :: a -> b

    instance X a a where foo = id
    instance X Int Bool where foo = (== 0)

But if instead you specify
    instance (a ~ b) => X a b where foo = id
you can't specify the Int Bool instance without overlap.

  -- ryan

On Mon, Jul 30, 2012 at 12:32 PM, Artyom Kazak <artyom.kazak at gmail.com>wrote:

> Hello,
>
> I have accidentally written my version of polyvariadic composition
> combinator, `mcomp`. It differs from Oleg’s version (
> http://okmij.org/ftp/Haskell/**polyvariadic.html#polyvar-comp<http://okmij.org/ftp/Haskell/polyvariadic.html#polyvar-comp>) in three aspects: a) it is simpler, b) it works without enumerating basic
> cases (all existing types, in other words), and c) it needs more type
> extensions.
>
>  {-# LANGUAGE
>>       MultiParamTypeClasses
>>     , FunctionalDependencies
>>     , FlexibleInstances
>>     , UndecidableInstances
>>     , TypeFamilies      , OverlappingInstances
>>   #-}
>>
>> class Mcomp a ar b br | a br -> b where
>>   mcomp :: a -> (ar -> br) -> b
>>
>> instance (a ~ ar, b ~ br) => Mcomp a ar b br where
>>   mcomp a f = f a
>>
>> instance (Mcomp a ar b br) => Mcomp (x -> a) ar (x -> b) br where
>>   mcomp a f = \x -> mcomp (a x) f
>>
>
> My question is: why doesn’t it work when I replace
>
>     instance (a ~ ar, b ~ br) => Mcomp a ar b br
>
> with
>
>     instance Mcomp a a b b
>
> ? I thought that equal letters mean equal types…
>
> ______________________________**_________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/**mailman/listinfo/haskell-cafe<http://www.haskell.org/mailman/listinfo/haskell-cafe>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120730/587d6ec5/attachment.htm>


More information about the Haskell-Cafe mailing list