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

Jan Bracker jan.bracker at googlemail.com
Tue Feb 28 16:46:49 UTC 2017


Hi,

As mentioned before there are several ways of doing this.

1. Constrain the functions working with your types keeping the type itself
unconstrained.

2. Write/Use a replacement for the Functor class that allows you to do
this. This will usually involve associated type synonyms or functional
dependencies. In my own work [1] I use associated type synonyms to do this.
But there are other libraries that wrote similar replacements for the
Functor class [2,3 and probably some more]. So if you want to use these you
fill have to swap out the Functor (Applicative and Monad) hierarchy with
another one that supports constraints.

So this is definitly possible and no limitation of GHC. The standard
library just does not allow it.

Categorically a standard functor goes from the category Hask to Hask.
A restricted or constrained functor can be seen as a functor that goes from
a category C (Hask with the constraints) to Hask together with an injective
functor that embeds C in a subcategory of Hask (which allows you to use it
in Haskell).

Best,
Jan

[1]:
http://hackage.haskell.org/package/supermonad-0.1/docs/Control-Supermonad-Constrained-Functor.html
[2]:
https://hackage.haskell.org/package/rmonad-0.8.0.2/docs/Control-RMonad.html#t:RFunctor
[3]:
http://hackage.haskell.org/package/constrained-monads-0.1.0.0/docs/Control-Monad-Constrained.html#t:Functor


2017-02-28 12:00 GMT+00:00 <haskell-cafe-request at haskell.org>:

> I've done a bit of work on a library that allows you to `fmap` say over
> sets, (i.e. fmap :: Ord a, Ord b => (a -> b) -> Set a -> Set b) which is
> more powerful than Monofunctor as it doesn't require the types to be the
> same.
>
> And it will involve importing a new version of "Functor" and "fmap",
> however it should be largely backwards compatible.
>
> However, it still needs a little bit of work to be in a state ready to be
> uploaded to Hackage (and even then, it probably needs even more work) but
> I'll give you a buzz when its up, hopefully in the next week or so.
>
> On Tue, Feb 28, 2017 at 2:01 PM, Guru Devanla <gurudev.devanla at gmail.com>
> wrote:
>
> > Thanks, Will.  I think adding  the constraint to the functions is a good
> > idea. Plus, it makes the intent clearer at the function level.
> >
> >
> >
> > On Mon, Feb 27, 2017 at 6:02 PM, Will Yager <will.yager at gmail.com>
> wrote:
> >
> >> 1. You could use MonoFunctor (complicated and probably not a good idea
> >> here) or just put the Taskable constraint on functions instead of on the
> >> Task definition (good and easy).
> >>
> >> So it would be
> >>
> >> data Task a = Task a deriving Functor
> >>
> >> And then put "Taskable a" on functions that require it.
> >>
> >> 2. You can't do it because it doesn't really make sense. A big part of a
> >> functor is that it has to be totally agnostic of what it's parametrized
> >> over. Otherwise you could easily violate the functor laws.
> >>
> >> Good question though, I used to wonder the same thing.
> >>
> >> cheers,
> >> Will
> >>
> >> On Feb 27, 2017, at 6:48 PM, 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.
> >>
> >>
> >
> > _______________________________________________
> > 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/20170228/0d255034/attachment-0001.html>
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>
>
> ------------------------------
>
> End of Haskell-Cafe Digest, Vol 162, Issue 33
> *********************************************
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20170228/594b8d2d/attachment.html>


More information about the Haskell-Cafe mailing list