David Menendez wrote:
Brian Hulley writes:

1) Did Edison choose MonadPlus just because this fitted in with the
lack of multi-parameter typeclasses in H98?

Instances of Monoid (and your ISeq) have kind *. Instances of
MonadPlus (and Edison's Sequence) have kind * -> *.

Functions like map, zip, and their variants are best defined in terms
of type constructors.

With Sequence, you have

    zipWith :: (Sequence s) => (a -> b -> c) -> s a -> s b -> s c

With ISeq, you'd have to do something like

    zipWith :: (ISeq s1 a, ISeq s2 b, ISeq s3 c) =>
        (a -> b -> c) -> s1 -> s2 -> s3

which isn't able to make any assumptions about s1, s2, and s3 having
the same structure.

On the other hand it's more powerful because they can now have different structures ie was there any reason not to have:

zipWith ::
     (Sequence s1, Sequence s2, Sequence s3) =>
     (a -> b -> c) -> s1 a -> s2 b -> s3 c


3) Is it worth bothering to derive ISeq from Monoid (with the
possible extra inefficiency of the indirection through the
definitions for append = mappend etc or does the compiler completely
optimize this out)?

I would expect the compiler to inline append.

Thanks - that's good news. I' probably still too much in C++ mode.

4) Would it be worth reconsidering the rules for top level names so
that class methods could always be local to their class (ditto for
value constructors and field names being local to their type
constructor).

Qualified module imports are the way to go, here. Do you really want
to start writing "if x Eq/== y Num/+ 1 then ... "?

I'm beginning to see that qualified module imports are indeed the only way to go, because the methods in a type class are only the "virtual" methods - often there are many other "methods" which are put outside the class to save space in the dictionary but which conceptually belong to the class thus putting the class + these extra functions in a single module wraps everything up into a conceptual unit.

eg:
     module Foldable
                     ( Foldable(..)
                     , reduceR
                     ) where

     class Foldable c a | c -> a where
        foldR :: (a -> b -> b) -> b -> [a] -> b
        -- ...

     reduceR :: Foldable c a => (a -> b -> b) -> (c -> b -> b)
     reduceR f xs y = foldR f y xs

forms the single conceptual unit to use Foldable.foldR, Foldable.reduceR etc so I'll have to retract my suggestion as regards classes... (Although I'm still concerned about value constructors and field names being in the top level instead of local to their type but changing this would require some changes to type inference (so that the constructors and field names could be used unqualified when the type at the given position is known eg by a top level type signature for the function or value) so that's more of a long term idea.)

Regards, Brian.

--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to