Artyom Kazak | 30 Jul 21:32 2012
Picon

Polyvariadic composition

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 ) 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
(Continue reading)

MigMit | 30 Jul 22:07 2012
Picon

Re: Polyvariadic composition

Works here.

GHC 7.4.2

On Jul 30, 2012, at 11: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 ) 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
> 
(Continue reading)

Ryan Ingram | 31 Jul 02:23 2012
Picon

Re: Polyvariadic composition

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 ) 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

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Gmane