Expressing disjunctions of constraints

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Expressing disjunctions of constraints

Olaf Klinke
Dear cafe,

today I wrote a type class with three parameters.

class Foo a b c | a b -> c where
  foo :: a -> b -> c
instance Foo A R A where ...
instance Foo R A A where ...

In addition to the functional dependency I'd like to express that at least one of the parameters a and b is c, that is, Foo is the union of the two classes

class Foo1 a b where
  foo1 :: a -> b -> a
class Foo2 a b where
  foo2 :: a -> b -> b

and furthermore the choice between Foo1 and Foo2 determines one parameter to be a fixed type, say R. I understand that logical disjunction poses problems for instance resolution [1] because adding an instance may affect the instance dictionary lookup. This should not happen in my case because in the end this would be a one-parameter type class. The ultimate aim is to use the same symbol for both a function
foo :: R -> a -> a
and for flip foo. Of course writing flip foo is not that much of a nuisance, I just wonder whether Haskell is expressive enough to do this.

Olaf

[1] https://stackoverflow.com/questions/10255148/how-can-i-combine-two-type-constraints-with-a-logical-or-in-haskell


_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: Expressing disjunctions of constraints

Paul
 > I'd like to express that at least one of the parameters a and b is c

Hello, Olaf! I never do it, but as idea: may be to use type-level lists,
for example, and to add such condition in instance constraints? There is
package type-lists with types "functions" like Find, etc (for member
checking, appending, etc)...


23.07.2018 22:54, Olaf Klinke wrotes:

> Dear cafe,
>
> today I wrote a type class with three parameters.
>
> class Foo a b c | a b -> c where
>    foo :: a -> b -> c
> instance Foo A R A where ...
> instance Foo R A A where ...
>
> In addition to the functional dependency I'd like to express that at least one of the parameters a and b is c, that is, Foo is the union of the two classes
>
> class Foo1 a b where
>    foo1 :: a -> b -> a
> class Foo2 a b where
>    foo2 :: a -> b -> b
>
> and furthermore the choice between Foo1 and Foo2 determines one parameter to be a fixed type, say R. I understand that logical disjunction poses problems for instance resolution [1] because adding an instance may affect the instance dictionary lookup. This should not happen in my case because in the end this would be a one-parameter type class. The ultimate aim is to use the same symbol for both a function
> foo :: R -> a -> a
> and for flip foo. Of course writing flip foo is not that much of a nuisance, I just wonder whether Haskell is expressive enough to do this.
>
> Olaf
>
> [1] https://stackoverflow.com/questions/10255148/how-can-i-combine-two-type-constraints-with-a-logical-or-in-haskell
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: Expressing disjunctions of constraints

Benjamin Fox
In reply to this post by Olaf Klinke
You could write a type family like this one:

type family (x :: k) `IsOneOf` (y :: (k, k)) :: Bool where
  x `IsOneOf` '(x, _) = 'True
  x `IsOneOf` '(_, x) = 'True
  _ `IsOneOf` _ = 'False

This is a type family that checks if a given type matches at least one of a given pair of types.

Once you have that, you can easily add it as a constraint to your typeclass:

class c `IsOneOf` '(a, b) ~ 'True => Foo a b c | a b -> c where
  foo :: a -> b -> c

This seems to give you what you want: It means that no instance of your typeclass can be for types a, b, and c such that c that isn't equal to at least one of a or b.


On Mon, Jul 23, 2018 at 9:55 PM Olaf Klinke <[hidden email]> wrote:
Dear cafe,

today I wrote a type class with three parameters.

class Foo a b c | a b -> c where
  foo :: a -> b -> c
instance Foo A R A where ...
instance Foo R A A where ...

In addition to the functional dependency I'd like to express that at least one of the parameters a and b is c, that is, Foo is the union of the two classes

class Foo1 a b where
  foo1 :: a -> b -> a
class Foo2 a b where
  foo2 :: a -> b -> b

and furthermore the choice between Foo1 and Foo2 determines one parameter to be a fixed type, say R. I understand that logical disjunction poses problems for instance resolution [1] because adding an instance may affect the instance dictionary lookup. This should not happen in my case because in the end this would be a one-parameter type class. The ultimate aim is to use the same symbol for both a function
foo :: R -> a -> a
and for flip foo. Of course writing flip foo is not that much of a nuisance, I just wonder whether Haskell is expressive enough to do this.

Olaf

[1] https://stackoverflow.com/questions/10255148/how-can-i-combine-two-type-constraints-with-a-logical-or-in-haskell


_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.