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

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-Co...
[2]:
https://hackage.haskell.org/package/rmonad-0.8.0.2/docs/Control-RMonad.html#...
[3]:
http://hackage.haskell.org/package/constrained-monads-0.1.0.0/docs/Control-M...
2017-02-28 12:00 GMT+00:00
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
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
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
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.
participants (1)
-
Jan Bracker