Removing polymorphism from type classes (viz. Functor) (Again)

I was inspired by George Pollard's posthttp://www.haskell.org/pipermail/haskell-cafe/2009-July/063981.htmlat haskell-cafe and tried to implement the non-polymorphic Functor class ( I named it Functor' ). I changed some names and added reasonable constraints. type family NewPt f a class Functor' f where type Point f map ∷ (a ~ Point f, b ~ Point g, g ~ NewPt f b, Functor' g) ⇒ (a → b) → f → g I would like to be able to write: type OldPt f = NewPt f (Point f) class (f ~ OldPt f) ⇒ Functor' f ... but ghc says it's not implemented yet (version 6.12.1). However, it's not the main problem. Now I can write some instances: type instance NewPt [a] b = [b] instance Functor' [a] where type Point [a] = a map = fmap type instance NewPt ByteString a = ByteString instance Functor' ByteString where type Point ByteString = Word8 map = BS.map But I can't write instance for Set: type instance NewPt (Set a) b = Set b instance Ord a ⇒ Functor' (Set a) where type Point (Set a) = a map = Set.map ghci complains: Could not deduce (Ord a1) from the context (g ~ NewPt (Set a) a1, a1 ~ Point g, Functor' g) arising from a use of `Set.map' at ... The type of Set.map is Set.map :: (Ord a, Ord b) => (a -> b) -> Set a -> Set b (Ord a) is in the instance context, and what about b? Type of map for Set instance would be: original: map ∷ (a ~ Point f, b ~ Point g, g ~ NewPt f b, Functor' g) ⇒ (a → b) → f → g substitute: f → Set a, g → Set b map :: Functor' (Set b) ⇒ (a →b) →Set a →Set b (Ord b) must be deduced from (Functor (Set b)) but it doesn't. I don't know whether it's my mistake somewhere or ghc problem. (Sorry for my English, it's not perfect). -- All the best, Alexey

Alexey Karakulov
(Ord b) must be deduced from (Functor (Set b)) but it doesn't. I don't know whether it's my mistake somewhere or ghc problem.
I've come across this problem as well; the best solution I've seen so far is the one taken by Ganesh in his rmonad library: http://hackage.haskell.org/package/rmonad -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

On Sat, Aug 14, 2010 at 2:27 PM, Ivan Lazar Miljenovic < ivan.miljenovic@gmail.com> wrote:
Alexey Karakulov
writes: (Ord b) must be deduced from (Functor (Set b)) but it doesn't. I don't know whether it's my mistake somewhere or ghc problem.
I've come across this problem as well; the best solution I've seen so far is the one taken by Ganesh in his rmonad library: http://hackage.haskell.org/package/rmonad
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com
Thanks for the link, but RFunctor typeclass is still (more or less) polymorphic, so I couldn't write ByteString instance for it. (Really I don't care about ByteString, but it's good example). However, I could try to use Suitable+Constraints concept for non-polymorphic functors. -- All the best, Alexey

The non-type-changing map can be implemented as a type class - in my graphics lib Wumpus, I call it pointwise: class Pointwise sh where type Pt sh :: * pointwise :: (Pt sh -> Pt sh) -> sh -> sh I think other people have posted it to the cafe under a different name, before I did: http://www.haskell.org/pipermail/haskell-cafe/2010-July/079784.html If I was doing Wumpus again though, I'd probably do with Pointwise. Best wishes Stephen

On 14 August 2010 20:27, Stephen Tetley
If I was doing Wumpus again though, I'd probably do with Pointwise.
Ahem, "do without Pointwise" Originally the types I operated on with Pointwise were more complicated than they are now and Pointwise seemed a benefit. But as I got a better understanding of the domain I was working in, I could simply my types; after doing this Pointwise has become rather superfluous.

Alexey Karakulov
(Ord b) must be deduced from (Functor (Set b)) but it doesn't. I don't know whether it's my mistake somewhere or ghc problem.
I've come across this problem as well; the best solution I've seen so far is the one taken by Ganesh in his rmonad library: http://hackage.haskell.org/package/rmonad
Thanks for the link, but RFunctor typeclass is still (more or less) polymorphic, so I couldn't write ByteString instance for it. (Really I don't care about ByteString, but it's good example). However, I could try to use Suitable+Constraints concept for non-polymorphic functors.
Yeah, I'm working on something like this at the moment, but I'm currently stuck on naming: if I want to have Functor for kind * -> *, what's a good name for a type class for kind *? Also, is there any type for which having a map a -> a _doesn't_ make sense? Bloomfilters maybe? -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

On 15 August 2010 08:50, Ivan Lazar Miljenovic
Yeah, I'm working on something like this at the moment, but I'm currently stuck on naming: if I want to have Functor for kind * -> *, what's a good name for a type class for kind *?
Conor McBride has suggested looking at arity families of functor-like things (functor, traversable, foldable, halfzippable(?)) may be worthwhile: http://www.haskell.org/pipermail/haskell-cafe/2008-June/044011.html Functors and bi-functors have obvious names, but naming zero arity and three-and-higher ones would need systematic treatment.

On Sun, Aug 15, 2010 at 10:50 AM, Ivan Lazar Miljenovic < ivan.miljenovic@gmail.com> wrote: Yeah, I'm working on something like this at the moment, but I'm
currently stuck on naming: if I want to have Functor for kind * -> *, what's a good name for a type class for kind *?
I was thinking about EtaFunctor, which stands for η-expanded Functor. But I'm not sure about η-expansion is correct term for removing polymorphism from the type class. Also, is there any type for which having a map a -> a _doesn't_ make
sense? Bloomfilters maybe?
Not the answer, but there are cases where having a map (a -> b) -> f -> g could make some new sense: data BitList = ... fromBoolList :: [Bool] -> BitList type instance NewPt [a] b = [b] type instance NewPt [a] Bool = BitList But this kind of overlapping type instance is not allowed in ghc (yet?) -- All the best, Alexey
participants (3)
-
Alexey Karakulov
-
Ivan Lazar Miljenovic
-
Stephen Tetley