
Hello Taral, Tuesday, August 15, 2006, 3:11:37 AM, you wrote:
Do we complain about a duplicate instance declarations?
yes. after all, this is just syntax sugar of giving both declarations:
Not necessarily. If A doesn't have any Functor declarations, it could be considered just a Monad without a Functor.
in this case we lose "class Functor a => Monad a" base class declaration. so what will be the meaning of this: class Monad m where instance Functor m return :: ... .... and this: class Monad m where instance Functor m where fmap = return ... return :: ... .... ? -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On 8/15/06, Bulat Ziganshin
in this case we lose "class Functor a => Monad a" base class declaration. so what will be the meaning of this:
I don't see why that is the case.
class Functor m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
instance Functor m where
fmap f = (>>= return . f)
What's wrong with this? All Monads are Functors. If you don't provide
a Functor, it gets defined for you. The problem is working out whether
to use the default Functor or an external Functor.
--
Taral

On 2006-08-15 at 16:25CDT Taral wrote:
On 8/15/06, Bulat Ziganshin
wrote: in this case we lose "class Functor a => Monad a" base class declaration. so what will be the meaning of this:
I don't see why that is the case.
class Functor m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b instance Functor m where fmap f = (>>= return . f)
What's wrong with this? All Monads are Functors. If you don't provide a Functor, it gets defined for you. The problem is working out whether to use the default Functor or an external Functor.
It seems obvious to me that we always use an external definition if one exists, so I suppose the problem is knowing whether an external instance exists -- so this proposal would rely on doing something about scoping for instances, I suppose. -- Jón Fairbairn Jon.Fairbairn at cl.cam.ac.uk

Am Dienstag, 15. August 2006 23:34 schrieb Jon Fairbairn:
On 2006-08-15 at 16:25CDT Taral wrote:
On 8/15/06, Bulat Ziganshin
wrote: in this case we lose "class Functor a => Monad a" base class declaration. so what will be the meaning of this:
I don't see why that is the case.
class Functor m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b instance Functor m where fmap f = (>>= return . f)
What's wrong with this? All Monads are Functors. If you don't provide a Functor, it gets defined for you. The problem is working out whether to use the default Functor or an external Functor.
It seems obvious to me that we always use an external definition if one exists, so I suppose the problem is knowing whether an external instance exists -- so this proposal would rely on doing something about scoping for instances, I suppose.
I see a solution in different ways of writitng an instance: [code] -- to define the functions in the Functor, using the defaults defined in the class _Functor_ (assumed there would be any default): instance Monad m where return = ... (>>=) = ... instance Functor m where -- to define the functions in the Functor, using the defaults defined in the class _Monad_: instance Monad m where return = ... (>>=) = ... instance Functor m where --to define a new Functor: instance Monad m where return = ... (>>=) = ... instance Functor m where fmap = ... --or instance Monad m where return = ... (>>=) = ... instance Functor m where fmap = ... [/code] the advantages are, that we can decide which default functions we want to use, and that it will be compatible to the old library. - marc

... P.S.: sth like nested instances (FFunctor) should be possible, too. and a way to select the defaults in external inteface definitions: "instance Monad M . Functor M where". maybe additional syntactic sugar (instances)? [code] class FFunctor m where ffmap :: ... class FFunctor m => Functor m where fmap :: ... instance FFunctor m where ffmap = fmap class Gunctor m where gmap :: ... class Hunctor m where hmap :: ... hmap = unsafePerformIO $ putStrLn "class Hunctor" >> undefined class FFunctor m => Junctor m where jmap :: ... jmap = unsafePerformIO $ putStrLn "class Junctor" >> undefined instance FFunctor m where ffmap = jmap class FFunctor m, Functor m, Gunctor m, Hunctor m, Junctor m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b instance Functor m where fmap f = unsafePerformIO $ putStrLn "class Monad" >> undefined --instance FFunctor m where instance Hunctor m where hmap f = unsafePerformIO $ putStrLn "class Monad" >> undefined instance Junctor m . FFunctor m where -- to define the functions in the *unctor, using the defaults defined in the class _*unctor_ (assumed there would be any default): instance Monad M where return = ... (>>=) = ... instance Functor M where gmap = unsafePerformIO $ putStrLn "instance Functor" >> undefined instance FFunctor M where instance Gunctor M where gmap = unsafePerformIO $ putStrLn "instance Gunctor" >> undefined instance Hunctor M where instance Junctor M where -- to define the functions in the *unctor, using the defaults defined in the class _Monad_: instance Monad M where return = ... (>>=) = ... instance Functor M where instance FFunctor M where instance Gunctor M where gmap = unsafePerformIO $ putStrLn "instance Monad" >> undefined instance Hunctor M where instance Junctor M where --or instance Monad M where return = ... (>>=) = ... instance Monad M . Functor M where instance Functor M . FFunctor M where --instance Monad M . FFunctor M where instance Monad M . Gunctor M where gmap = unsafePerformIO $ putStrLn "instance Monad" >> undefined instance Monad M . Hunctor M where instance Monad M . Junctor M where --syntactic sugar: instance Monad M where return = ... (>>=) = ... instances Functor M, Gunctor M, Junctor M where gmap = unsafePerformIO $ putStrLn "instance Monad" >> undefined instances Hunctor M, Junctor M . FFunctor M where [/code] - marc

On Tue, Aug 15, 2006 at 10:34:39PM +0100, Jon Fairbairn wrote:
It seems obvious to me that we always use an external definition if one exists, so I suppose the problem is knowing whether an external instance exists -- so this proposal would rely on doing something about scoping for instances, I suppose.
The problem is you can't have working code change its behavior because of a module import (other than failing), say, by bringing an instance into scope that wasn't before. There is no way to have a monad instance 'automatically' declare a functor instance without changing what the mo instance looks like somehow which would be a backwards incompatable change. John -- John Meacham - ⑆repetae.net⑆john⑈

John Meacham
On Tue, Aug 15, 2006 at 10:34:39PM +0100, Jon Fairbairn wrote:
It seems obvious to me that we always use an external definition if one exists, so I suppose the problem is knowing whether an external instance exists -- so this proposal would rely on doing something about scoping for instances, I suppose.
The problem is you can't have working code change its behavior because of a module import (other than failing), say, by bringing an instance into scope that wasn't before. There is no way to have a monad instance 'automatically' declare a functor instance without changing what the mo instance looks like somehow which would be a backwards incompatable change.
In that case we really ought just to accept that we have to declare the instances and swallow class Functor m => Monad m where ... without any cleverness. * * * another, more adventurous path would be to find a set of restrictions that allow one to define instance Monad m => Functor m where fmap f = (>>= f . return) without it being undecidable. (I don't really like this, because it seems to be backwards). -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html (updated 2006-07-14)

Jón Fairbairn
John Meacham
writes: The problem is you can't have working code change its behavior because of a module import (other than failing), say, by bringing an instance into scope that wasn't before. There is no way to have a monad instance 'automatically' declare a functor instance without changing what the mo instance looks like somehow which would be a backwards incompatable change.
In that case we really ought just to accept that we have to declare the instances and swallow
class Functor m => Monad m where ...
without any cleverness.
Or, alternatively, make my previous suggestion less automatic. I was suggesting that we could allow default instances of superclasses in class declarations; we'd say
class Functor m => Monad m where (>>=):: ... instance Functor m where fmap = ...<a> ...
what I'm proposing here is that we do that, but the "default" instances are never supplied automatically. Instead we allow a "deriving" clause on instance declarations:
instance Monad [] deriving Functor where ...
Now this would be exactly equivalent to
instance Monad [] where ... instance Functor [] where fmap = ...<a>
(and just as much an error if there's another instance declaration for Functor somwhere), while an instance declaration without the deriving clause would not say anything about a Functor instance at all. So, not fully automatic -- so avoiding the above problem, but more concise than a whole instance declaration. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

Hello Taral, Wednesday, August 16, 2006, 1:25:03 AM, you wrote:
in this case we lose "class Functor a => Monad a" base class declaration. so what will be the meaning of this:
I don't see why that is the case.
class Functor m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b instance Functor m where fmap f = (>>= return . f)
What's wrong with this? All Monads are Functors. If you don't provide a Functor, it gets defined for you. The problem is working out whether to use the default Functor or an external Functor.
you deleted context of my note, where you wrote something opposite to "All Monads are Functors":
Not necessarily. If A doesn't have any Functor declarations, it could be considered just a Monad without a Functor.
is it possible to declare Monad Foo without Functor Foo with the above class definition? i think no. Functor instance will be either defaulted or explicitly defined. so both modules, A and B, actually defines _both_ instances, although A defines Functor Foo implicitly while B does it explicitly. importing both modules will mean importing two different declaration of both instances, Functor Foo and Monad Foo -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On 8/16/06, Bulat Ziganshin
you deleted context of my note, where you wrote something opposite to "All Monads are Functors":
Not necessarily. If A doesn't have any Functor declarations, it could be considered just a Monad without a Functor.
is it possible to declare Monad Foo without Functor Foo with the above class definition?
You misunderstood what I meant. "Monad without a Functor" means Monad
*declaration* without an explicit Functor *declaration*, i.e. using
the defaults. The problem happens when a definition implicitly uses
the defaults and then an explicit Functor comes into scope via import.
The current proposal to require people to write "instance Functor"
isn't so pretty as the hierarchy becomes more fine-grained:
instance Monad [] where
instance Functor
instance PointedFunctor
instance Applicative
...
--
Taral
participants (6)
-
Bulat Ziganshin
-
John Meacham
-
Jon Fairbairn
-
Jón Fairbairn
-
Marc A. Ziegert
-
Taral