[Haskell-beginners] help on writing a typeclass

Silent Leaf silent.leaf0 at gmail.com
Fri Jun 3 23:57:54 UTC 2016


Got an idea, is it the right path? Are there bad consequences in using the
extensions that are necessaries to make the code work?

class Mdk binary a | binary -> a where
mdk :: a -> b -> binary
instance Mdk (a,b) a where
mdk = ... :: a -> b -> (a,b)
instance Mdk (b, a) a where
mdk = ... :: a -> b -> (b, a)

then, however, even if it works, mdk will never be part of the other class
i was working on, and at that point i'm a bit lost on the consequences of
this...

Le samedi 4 juin 2016, Silent Leaf <silent.leaf0 at gmail.com> a écrit :
> I got a function, named mdk (don't ask). It happens it's a method of a
class, as follows:
>
> class C a where
>  mdk :: C b => a -> b -> (a, b)
>
> yet i got another function, called so far mdk'
>  mdk' :: C b => b -> a -> (a, b)
>
>
> Say there are the following instances:
> instance C X where
>  mdk x b = ... :: C b => (X, b)
>  mdk' b x = ... :: C b => (X, b)
> instance C Y where
>  mdk y b = ... :: C b => (Y, b)
>  mdk' b y = ... :: C b => (Y, b)
>
> if you get what's happening, mdk and mdk' are basically the same method,
save for the final type-result, which is reversed, without data loss mind
you (aka (A, B) and (B, A) could be the same type, if only i knew of a way
to make a type in haskell without forcing the order (a kind of set or
something).
> so, there are four cases:
> input have types, in this order, X and Y, and expected output is (X, Y):
then mdk from X's instance of C is called/must be used;
> input have types Y and X, output (X, Y): X's mdk'
> input X and Y, output (Y, X): Y's mdk
> input Y and X, output (Y, X): Y's mdk'
>
> it might seem confusing, but all amounts to the issue that even though
(Y, X) is strictly equivalent, in my program, to (X, Y), in principle
haskell differentiate the types.
> thus i have to write two versions of mdk for each type, even though the
methods "X's mdk" and "Y's mdk'" are identical, and same for the two other
methods.
> indeed:
> mdk :: C b => X -> b -> (X, b)
> mdk' :: C b => b -> Y -> (Y, b)
> are identical signatures, if in the first one you replace `b` with Y, and
in the latter you replace `b` with X, and ofc if you consider (X,Y) ==
(Y,X).
>
> only one of those two methods should be enough to handle the job, and be
chosen by the compiler on the sole value of the type of the first variable;
but the fact both methods return tuples of "mirrored" types, crushes that.
if i only write `mdk` instances, as soon as the compiler will meet this
following signature:
>  mdk :: a -> b -> (b, a)
> it will crash an exception, because mdk's original signature has for
output value a tuple whose first type should here be `a`, because it's
meant to be the type of the first argument, not the second.
>
> thus, at last my question: can i tell the compiler to consider (b, a) and
(a, b) as identical types (don't worry it's not really a tuple in my
program, but it's equivalent)?
> if not, can i make an overloading of mdk so it accepts both a->b->(a,b)
and a->b->(b,a)?
>
> hope i didn't lose anyone. if so, do tell me, i'll try to clarify.
>
> thanks in advance of the time spent trying to understand my problem!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20160604/76a7c73f/attachment-0001.html>


More information about the Beginners mailing list