Can some body explain me the signature of Functor.
Prelude> :info Functor
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
I don't understand what * means.
* is the syntax used by Haskell for kinds
In this case it means that f is higher-kinded (think functions on the type level)
Here f is taking one type (the first *) and is producing another type (the second *)
you can basically forget all this here and just read it as:
class Functor f where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
but it's a nice documentation IMO and there are quite a few classes that are more complicated and the kind-signature is really helpful - for example:
class MonadTrans (t :: (* -> *) -> * -> *) where
lift :: Monad m => m a -> t m a
-- Defined in `Control.Monad.Trans.Class'
Here t takes a type-constructor itself (the Monad) together with another type and produces a type again.
Related
Consider the following wishful program.
{-# LANGUAGE ExtensibleGADTs #-}
data Free a where
Lift :: a -> Free a
data Free (f a) => FreeFunctor f a where
Map :: (a -> b) -> FreeFunctor f a -> FreeFunctor f b
instance Functor (FreeFunctor f) where
fmap = Map
data FreeFunctor f a => FreeApplicative f a where
Apply :: FreeApplicative f (a -> b) -> FreeApplicative f a -> FreeApplicative f b
Pure :: a -> FreeApplicative f a
instance Applicative (FreeApplicative f) where
(<*>) = Apply
pure = Pure
data FreeApplicative m a => FreeMonad m a where
Bind :: FreeMonad m a -> (a -> FreeMonad m b) -> FreeMonad m b
instance Monad (FreeMonad m) where
(>>=) = Bind
This would introduce a notion of substitutability. For example, a FreeApplicative f a can be substituted by a FreeFunctor f a but not a FreeMonad f a. Similarly, a FreeApplicative f a -> Int can be substituted by a FreeMonad f a -> Int but not a FreeFunctor f a -> Int.
The notion of subtyping can be captured using injections.
import Unsafe.Coerce
fromFreeToFreeFunctor :: Free (f a) -> FreeFunctor f a
fromFreeToFreeFunctor = unsafeCoerce
fromFreeFunctorToFreeApplicative :: FreeFunctor f a -> FreeApplicative f a
fromFreeFunctorToFreeApplicative = unsafeCoerce
fromFreeApplicativeToFreeMonad :: FreeApplicative m a -> FreeMonad m a
fromFreeApplicativeToFreeMonad = unsafeCoerce
The compiler would insert these injections as and where required.
I think that this is a good solution to the expression problem. However, the general consensus is that subtype polymorphism would be problematic in Haskell. So, my question is two fold.
Would subtyping, as I described above, be problematic or interfere with type inference in Haskell?
Would extensible GADTs be a viable solution to the expression problem in Haskell?
I haven't defined a precise semantics for extensible GADTs yet. If this seems like something worth pursuing then I'd like to write a GHC extension for this. Just wanted to put this idea out in the wild and get some criticism.
I've got a type t that supports the following three operations:
extract :: t a -> a
duplicate :: t a -> t (t a)
(<*>) :: t (a -> b) -> t a -> t b
Naturally I can also write bind:
(>>=) :: f a -> (a -> f b) -> f b
(>>=) x f = f (extract x)
And join:
join :: t (t a) -> t a
join = extract
But I can't write fmap nor pure
So this is kind of a "monad", and kind of a "comonad", but without fmap.
Technically, I have got an fmap and pure, but they're constrained.
I looked at various constrained functor style packages, but they all seem to constrain (<*>) as well, but in my case (<*>) is not constrained.
Is there an existing typeclass I could squeeze this type into?
If anyone is interested, the actual type I'm dealing with is the Closure type
Why does GHCI add constraint for the required context here:
> let f = fmap show
> :t f
f :: (Functor f, Show a) => f a -> f String
But not here?
> :t over
over :: Lens s t a b -> (a -> b) -> s -> t
> :t _all'
_all' :: (Applicative f, Eq a) => a -> (a -> f a) -> [a] -> f [a]
> :t over (_all' 2)
<interactive>:1:7: error:
• Could not deduce (Applicative f) arising from a use of ‘_all'’
Is there any major difference between these two cases?
Note that isn't the type of over as defined by the lens library. That being said, your version doesn't work because Lens is
type Lens = forall f. Functor f => (a -> f b) -> s -> f t
and
_all' 2 :: forall f. Applicative f => ..
In other words, over is demanding a function which works for any Functor, but you've provided one which only works for Applicative (which is a stronger constraint, in that Functor doesn't imply Applicative).
Comment by #user2407038.
As alluded to in the comment, you can fix your problem by fixing the type signature for over. It should either be the complicated fancy thing in lens using distributive functors or the simpler
type Setter s t a b = (a -> Identity b) -> s -> Identity t
over :: Setter s t a b -> (a -> b) -> s -> t
As the identity type is both a functor and an applicative, it unifies with lenses and (I assume in your case) traversals.
Monads get fmap from Functor typeclass. Why comonads don't need a cofmap method defined in a Cofunctor class?
Functor is defined as:
class Functor f where
fmap :: (a -> b) -> (f a -> f b)
Cofunctor could be defined as follows:
class Cofunctor f where
cofmap :: (b -> a) -> (f b -> f a)
So, both are technically the same, and that's why Cofunctor does not exist. "The dual concept of 'functor in general' is still 'functor in general'".
Since Functor and Cofunctor are the same, both monads and comonads are defined by using Functor. But don't let that make you think that monads and comonads are the same thing, they're not.
A monad is defined (simplifying) as:
class Functor m => Monad where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
whether a comonad (again, simplified) is:
class Functor w => Comonad where
extract :: w a -> a
extend :: (w a -> b) -> w a -> w b
Note the "symmetry".
Another thing is a contravariant functor, defined as:
import Data.Functor.Contravariant
class Contravariant f where
contramap :: (b -> a) -> (f a -> f b)
For reference,
class Functor w => Comonad w where
extract :: w a -> a
duplicate :: w a -> w (w a)
extend :: (w a -> b) -> w a -> w b
instance Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
join :: Monad m => m (m a) -> m a
Note that given extract and extend you can produce fmap and duplicate, and that given return and >>= you can produce fmap, pure, <*>, and join. So we can focus on just pure+>>= and extract+extend.
I imagine you might be looking for something like
class InverseFunctor f where
unmap :: (f a -> f b) -> a -> b
Since the Monad class makes it easy to "put things in" while only allowing a sort of hypothetical approach to "taking things out", and Comonad does something opposed to that, your request initially sounds sensible. However, there is a significant asymmetry between >>= and extend that will get in the way of any attempt to define unmap. Note in particular that the first argument of >>= has type m a. The second argument of extend has type w a—not a.
Actually, you're wrong: there is one!
https://hackage.haskell.org/package/acme-cofunctor
What is the general term for a functor with a structure resembling QuickCheck's promote function, i.e., a function of the form:
promote :: (a -> f b) -> f (a -> b)
(this is the inverse of flip $ fmap (flip ($)) :: f (a -> b) -> (a -> f b)). Are there even any functors with such an operation, other than (->) r and Id? (I'm sure there must be). Googling 'quickcheck promote' only turned up the QuickCheck documentation, which doesn't give promote in any more general context AFAICS; searching SO for 'quickcheck promote' produces no results.
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
(=<<) :: Monad m => (a -> m b) -> m a -> m b
Given that Monad is more powerful an interface than Applicative, this tell us that a -> f b can do more things than f (a -> b). This tells us that a function of type (a -> f b) -> f (a -> b) can't be injective. The domain is bigger than the codomain, in a handwavey manner. This means there's no way you can possibly preserve behavior of the function. It just doesn't work out across generic functors.
You can, of course, characterize functors in which that operation is injective. Identity and (->) a are certainly examples. I'm willing to bet there are more examples, but nothing jumps out at me immediately.
So far I found these ways of constructing an f with the promote morphism:
f = Identity
if f and g both have promote then the pair functor h t = (f t, g t) also does
if f and g both have promote then the composition h t = f (g t) also does
if f has the promote property and g is any contrafunctor then the functor h t = g t -> f t has the promote property
The last property can be generalized to profunctors g, but then f will be merely a profunctor, so it's probably not very useful, unless you only require profunctors.
Now, using these four constructions, we can find many examples of functors f for which promote exists:
f t = (t,t)
f t = (t, b -> t)
f t = (t -> a) -> t
f t = ((t,t) -> b) -> (t,t,t)
f t = ((t, t, c -> t, (t -> b) -> t) -> a) -> t
Also note that the promote property implies that f is pointed.
point :: t -> f t
point x = fmap (const x) (promote id)
Essentially the same question: Is this property of a functor stronger than a monad?
Data.Distributive has
class Functor g => Distributive g where
distribute :: Functor f => f (g a) -> g (f a)
-- other non-critical methods
Renaming your variables, you get
promote :: (c -> g a) -> g (c -> a)
Using slightly invalid syntax for clarity,
promote :: ((c ->) (g a)) -> g ((c ->) a)
(c ->) is a Functor, so the type of promote is a special case of the type of distribute. Thus every Distributive functor supports your promote. I don't know if any support promote but not Distributive.