<div>Well, you&#39;re going to wind up with a lot of cases where you really want a quantified context, even with just your Functor definition, but in that same spirit you can build an &#39;Applicative-like&#39; instance as well. </div>

<div><br>&gt; type family Arg f :: *<br>&gt; type instance Arg [a -&gt; b] = [a]</div>
<div> </div>
<div>&gt; type family Result f :: *<br>&gt; type instance Result [a -&gt; b] = [b]</div>
<div> </div>
<div>&gt; class Pointed f =&gt; Applicative f where<br>&gt;     (&lt;*&gt;) :: f -&gt; Arg f -&gt; Result f </div>
<div> </div>
<div>&gt; instance Applicative [a -&gt; b] where<br>&gt;     fs &lt;*&gt; xs = do f &lt;- fs; map f </div>
<div> </div>
<div>The thing is these definitions are very hard to actually use. I have a similar construction for Foldable/Traversable-like containers in the &#39;monoids&#39; package as Data.Generator that you might want to look at for ideas.</div>

<div> </div>
<div>-Edward Kmett</div>
<div> </div>
<div class="gmail_quote">On Tue, Jul 7, 2009 at 7:03 PM, George Pollard <span dir="ltr">&lt;<a href="mailto:porges@porg.es">porges@porg.es</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">Ok, so I have a small idea I&#39;m trying to work on; call it a<br>Prelude-rewrite if you want. For this I want to be able to have the<br>
hierarchy Functor → Applicative → Monad.<br><br>For Functor, I would like to be able to implement it for a wider<br>variety of types, as there are types which have aren&#39;t polymorphic<br>which would also benefit from having an instance.<br>
My running example for this set of types is ByteString; the module<br>contains the method:<br><br>   map ∷ (Word8 → Word8) → ByteString → ByteString<br><br>However, we cannot use this for Functor because ByteString isn&#39;t<br>
polymorphic. To get around this, I devised the following:<br><br>Introduce a type family which represents ‘points’ inside the type:<br><br>   type family Point f ∷ ★<br><br>For ByteString we have:<br><br>   type instance Point ByteString = Word8<br>
<br>For a polymorphic example (lists) we have:<br><br>   type instance Point [a] = a<br><br>Now Functor becomes:<br><br>   class SimpleFunctor f where<br>       fmap ∷ (Point f → Point f) → (f → f)<br><br>However, this doesn&#39;t allow for the existence of functions with the<br>
type (a → b). I need to introduce another type into the class:<br><br>   class Functor f g where<br>       fmap ∷ (Point f → Point g) → (f → g)<br><br>But having two types isn&#39;t very nice (for one thing we can&#39;t introduce<br>
a fundep because for lists as it fails one of the coverage<br>conditions), so introduce another type family to represent types which<br>can be produced by giving a free variable:<br><br>   type Subst f a ∷ ★<br>   type Subst [a] b = [b]<br>
   type Subst ByteString b = ByteString<br><br>   class Functor f where<br>       fmap ∷ (Point f → Point (Subst f a)) → (f → Subst f a)<br><br>I&#39;m not sure how much of a hack this is, or if there is a better way.<br>
It seems to be OK...<br><br>Now I want to implement Applicative. It would make sense to have<br>‘return’ be split out into a separate class, because this can be<br>restricted in a similar way to Functor:<br><br>   class Pointed f where<br>
       return ∷ Point f → f<br><br>   instance Pointed [a] where<br>       return x = [x]<br><br>   instance Pointed ByteString where<br>       return = BS.singleton<br><br>Now, I want to be able to restrict Applicative to things which have<br>
[Pointed f, and forall a b. Point f ~ (a → b)]. At the moment I can&#39;t<br>figure this out because I believe it would require something like the<br>‘quantified contexts’ proposal:<br><br>   class (Pointed f, ∀ a b. Point f ~ (a → b)) ⇒ Applicative f where<br>
       ...<br><br>I could have something like:<br><br>   class (Pointed f, Point f ~ (a → b)) ⇒ Applicative f a b where<br>       apply ∷ f → Subst f a → Subst f b<br><br>This is still not very nice, because it requires two more type<br>
variables in the class, and the non-type-families version is far more<br>straightforward... in fact, it makes sense for the Applicative class<br>to have a polymorphic type because it must be able to have ‘return’<br>applied to arbitrary functions (remember [fmap f xs ≡ return f `apply`<br>
xs]). So back to:<br><br>   class Applicative f where<br>       apply ∷ f (a → b) → f a → f b<br><br>But then ‘return’ cannot be added via a superclass restriction to<br>Pointed! I seem to have painted myself into a corner. Does anyone see<br>
a better way to go about this?<br><br>Thanks,<br>- George<br>_______________________________________________<br>Haskell-Cafe mailing list<br><a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br><a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</blockquote></div><br>