[Haskell-cafe] Alternative to newtypes or orphan instances

Miguel Mitrofanov miguelimo38 at yandex.ru
Mon Aug 24 11:11:19 UTC 2015


> T is an instance of both C and C1

Then why the hell do you need C1 at all?

24.08.2015, 13:48, "Clinton Mead" <clintonmead at gmail.com>:
> After implementing the steps in (c), T is an instance of both C and C1, and both those instances define foo the same way. The only way I see a problem if is a module imports both C1 and C unqualified (they'll clash) but I see no reason to do that.
>
> On Monday, 24 August 2015, Clinton Mead <clintonmead at gmail.com> wrote:
>> Why does 'foo' fail? The module that 'foo'is defined in still can see C. C still exists. So as long as I import foo it should still work yes?
>>
>> On Monday, 24 August 2015, Miguel Mitrofanov <miguelimo38 at yandex.ru> wrote:
>>> OK. There is no point in having a class C, if there is no functions to work with it. So, this "other package" likely contains some functions that take types (of that class) as input. Like this:
>>>
>>> foo :: C a => a -> Int
>>>
>>> You don't need class C if you aren't using any functions from the library. So, with your (c), if you try to do
>>>
>>> a :: T
>>> a = ...
>>>
>>> b :: Int
>>> b = foo a
>>>
>>> you'll get a compile error. THAT is the problem.
>>>
>>> 24.08.2015, 13:28, "Clinton Mead" <clintonmead at gmail.com>:
>>>> There's no new data. Class C already exists in another package. Data T already exists in another different package.
>>>>
>>>> The options are:
>>>>
>>>> a) Create a newtype MyT and an instance MyT of C.
>>>> b) Just create an orphan instance T of C.
>>>> c) Create a new class C1, forward its implementation to C, and add an instance T of C1.
>>>>
>>>> I'm suggesting (c) is best, but I haven't seen this elsewhere, the debate is usually between (a) and (b).
>>>>
>>>> I don't really understand the problems you're proposing with (c), but I'm not sure if that's because I'm misunderstanding you or I'm not explaining myself well.
>>>>
>>>> On Monday, 24 August 2015, Miguel Mitrofanov <miguelimo38 at yandex.ru> wrote:
>>>>> If, for your data, you create an instance of the new class — but not the original one, then you can't use all the machinery that expects input being of the old class. Which is the point.
>>>>>
>>>>> 24.08.2015, 12:55, "Clinton Mead" <clintonmead at gmail.com>:
>>>>>> The original class still exists, I can't see how making a new class based on the old on affects that. Won't existing functions in modules which import the old class instead of the new class continue to work?
>>>>>>
>>>>>> On Monday, 24 August 2015, Erik Hesselink <hesselink at gmail.com> wrote:
>>>>>>> On 24 August 2015 at 09:18, Clinton Mead <clintonmead at gmail.com> wrote:
>>>>>>>> A second approach is an orphan instance. The recommendation here is to put
>>>>>>>> the orphan instances in their own module, so the user can choose to import
>>>>>>>> them.
>>>>>>>>
>>>>>>>> This may works ok if your user is writing an executable. But what if your
>>>>>>>> user is writing a library themselves. But once, you, or your user, directly
>>>>>>>> uses one of the instances, they need to import it, and they pollute the
>>>>>>>> global instance namespace for anyone that uses their package.
>>>>>>>
>>>>>>> For this reason, I think the recommended course of action is to make a
>>>>>>> canonical place for the instance, so that everyone can use it. For
>>>>>>> example, if you have a library 'foo' providing T, and a library 'bar'
>>>>>>> providing C, put the instance in a new package 'foo-bar' (or
>>>>>>> 'bar-foo'). Then everyone can use that one instance, since Haskell is
>>>>>>> built on the assumption that every type has one unique instance per
>>>>>>> class.
>>>>>>>
>>>>>>>> I want to suggest a third option:
>>>>>>>>
>>>>>>>> (3) Copying the class.
>>>>>>>
>>>>>>> This would make a new distinct class, which means you can't call any
>>>>>>> methods which have the original class as the context (f :: C a => a ->
>>>>>>> a) since that class won't exist for type T (you are trying to avoid
>>>>>>> defining that orphan instance). So I don't think this is usable in
>>>>>>> most cases, unless I'm missing something.
>>>>>>>
>>>>>>> Erik
>>>>>> ,
>>>>>>
>>>>>> _______________________________________________
>>>>>> Haskell-Cafe mailing list
>>>>>> Haskell-Cafe at haskell.org
>>>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe


More information about the Haskell-Cafe mailing list