
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