[Haskell-cafe] Declaring Functors for Type constrained data types

Guru Devanla gurudev.devanla at gmail.com
Wed Mar 1 13:16:02 UTC 2017


This problem I was solving is more of a re-implementation of some code  I
had in Python. In Python, I had a very class-based structure of this
design. By class based structure, I mean we have class-level methods for
each class (where each class  is a type of Task), and all of them implement
the same set of methods. This classes are never instantiated, but all
methods are invoked on the class.

WIth that perspective, the record patter @Patrick recommended directly maps
to that design. The record data type here becomes a abstract-representation
of my class(abstract base class in OO terms)  and each task provides its
methods.  I see that relationship.  Is that the approach I should be aiming
for?

Secondly, while choosing the type-class approach,  I imagined all these
required class methods to be an interface and therefore an interface could
directly map to a type class in Haskell.  Is that thinking usually an
anti-pattern.

The existential antipattern
<https://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/>.
link was very useful and made me re-asses my inclination to defining type
classes and embedded types right away.

On Tue, Feb 28, 2017 at 9:55 AM, Patrick Chilton <chpatrick at gmail.com>
wrote:

> You could also consider representing tasks like this instead of using a
> typeclass:
>
> data Task = Task
>   { process :: m ()
>   , canRun :: m Bool
>   }
>
> The Taskable + existential GADT example seems like it could be an example
> of the existential antipattern
> <https://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/>
> .
>
> If your GADT really does have a as a type parameter, it would be more
> idiomatic to check for the typeclass when you use it:
>
> doStuffWithTasks :: Taskable a => Task a -> ...
>
> But then what's the point of the Task datatype?
>
> On Tue, Feb 28, 2017 at 1:48 AM, Guru Devanla <gurudev.devanla at gmail.com>
> wrote:
>
>> Hello All,
>>
>> I am working on a program that will define a bunch of tasks. Each task
>> will have to implement certain methods as part of a type class.
>>
>> -- task 1
>> data UpdateAcctsTask = UpdateAccts
>>
>> -- task 2
>> data EmailConfig = EmaiConfig {someattrs::String}
>> data SendEmailTask = SendEmailsTask EmailConfig
>>
>> -- task 3
>> data GeneralWriterTask a = GeneralWriterTask a
>>
>> Each of these tasks implement a class, Taskable. The return
>> values are simplified for this example.
>>
>> class Taskable a where
>>   process :: a -> Bool
>>   can_run :: a -> Bool
>>
>>
>> This works fine. I can expand on these tasks and execute them.
>>
>> Now, I wanted to be able to defined dependencies between these
>> (Taskable's). I decided
>> I could create a data type for this dependency and may be also get a
>> FreeMonad
>> around this structure for further processing using a graph of Tasks. But,
>> before that I wanted
>> to create an wrapper for these Taskables and create a functor for it as
>> follows
>>
>> The first thing I did was, define a Task, which generalizes over all
>> the above defined (and future Taskables)
>>
>> data Task a where
>>   Task :: (Taskable a) => a -> Task a
>>
>>
>> instance Functor Task where
>>   fmap:: (Taskable a, Taskable b) -> (a -> b) -> Task a  -> Task b    ---
>> THIS DOES NOT WORK
>>   fmap f (Task a) = Task $ f a
>>
>>
>> But, I realized that I cannot define an fmap over a type constraint.
>>
>> My questions are:
>>
>> 1. Is there any way to do this. I see there is an answer of SO. I wanted
>>    to make sure if there were any improvements to this since that answer'
>>    was posted.
>>    http://stackoverflow.com/questions/17157579/functor-instance
>> -for-a-gadt-with-type-constraint
>>
>> 2. Secondly, I would like to know why this is not possible. Is it a
>> current
>>    limitation of GHC or if there is some fundamental category theory
>> concepts
>>    that dis-allows such declarations that I need to grok!
>>
>> Appreciate any help on this. Thank you!
>>
>> _______________________________________________
>> 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.
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20170301/04fa37ea/attachment.html>


More information about the Haskell-Cafe mailing list