When does GHCI not deduce the required context? - haskell

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.

Related

Confusion regarding composition in Haskell

I'm working through the Haskell book and I've realized I'm having a hard time understanding function composition. At a very basic level I have a mental model of a pipeline that takes an input and passes it's result to the next function in the composition. For simple functions this is very easy.
Where I'm having difficulty is understanding how the resulting type signatures of composing the functions come to be. For example, if we look at the base definition of elem:
elem :: (Foldable t, Eq a) => a -> t a -> Bool
elem = any . (==)
>:t (==)
(==) :: Eq a => a -> a -> Bool
>:t any
any :: Foldable t => (a -> Bool) -> t a -> Bool
I fail to see how the resulting type signature occurs. If I were given the function and asked to write the type signature I'd be hopelessly lost.
The same goes for the following. In the chapter on Traversable we were told that traverse is just sequenceA and fmap composed:
traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
traverse f = sequenceA . fmap f
>:t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
>:t sequenceA
sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
On their own I understand each functions type signature, but how do they combine to create traverse's type signature?
Super lost here, any help would be greatly appreciated.
Perhaps merely visually aligning the types will get you part of the way to some intuition about how the pipeline progresses, and help you make progress towards your next point of confusion!
(==) :: Eq a => a -> (a -> Bool)
any :: (a -> Bool) -> (t a -> Bool)
any . (==) :: Eq a => a -> (t a -> Bool)
To keep the next one on one screen, let's abbreviate Traversable to T and Applicative to A. You also have two fs in your question, one at the computation level and one at the type level. To avoid confusion, I'm going to rename your computation-level f to g instead. So if g :: a -> f b for some Applicative f:
fmap g :: T t => t a -> t (f b)
sequenceA :: (T t, A f) => t (f b) -> f (t b)
sequenceA . fmap g :: (T t, A f) => t a -> f (t b)
\g -> sequenceA . fmap g :: (T t, A f) => (a -> f b) -> t a -> f (t b)
(Wait! How come for fmap g, the constraint on t is Traversable and not Functor? Okay, no problem: we can actually give it the more relaxed type fmap g :: Functor t => .... But since every Traversable must be a Functor, it can also be given this type which makes the parallels more clear.)
All Haskell functions take just one argument -- even the ones we often think of as taking multiple arguments. Consider your elem example:
elem :: (Foldable t, Eq a) => a -> t a -> Bool
elem = any . (==)
>:t (==)
(==) :: Eq a => a -> a -> Bool
>:t any
any :: Foldable t => (a -> Bool) -> t a -> Bool
The type of (==) can be read as (==) :: Eq a => a -> (a -> Bool): it takes an a value (a can be anything which is an instance of Eq) and gives an a -> Bool function. any, in turn, takes an a -> Bool function (a can be anything) and gives a t a -> Bool function (t can be anything which is an instance of Foldable). That being so, the intermediate type in the any . (==) pipeline is Eq a => a -> Bool.

What monad style typeclass does this typeclass fit into?

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

Example of functions as applicatives, in foldMap and filter for foldables

In the first hunk, filterF is implemented with foldMap
import Data.List
pred :: a -> Bool
pred = undefined
wrapperOfA :: (Applicative f, Monoid (f a)) => a -> Bool -> f a
wrapperOfA a condition = if condition then pure a else mempty
-- foldMap :: (Foldable t, Monoid f a) => (a -> f a) -> t a -> f a
filterF :: (Applicative f, Foldable t, Monoid (f a)) => (a -> Bool) -> t a -> f a
filterF pred = foldMap ((<*>) wrapperOfA pred)
filterF (<3) [5,4,3,2,1] :: [Int]
-- [2,1]
... which utilises some Applicative's apply function, aka <*> typically infixed. Now, the type of <*> is:
:t (<*>)
--(<*>) :: forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
But replacing it with a hole gives its type as
-- (a0 -> Bool -> f0 a0) -> (a -> Bool) -> a -> f a
-- namely, from typechecking
filterF :: (Applicative f, Foldable t, Monoid (f a)) => (a -> Bool) -> t a -> f a
filterF pred = foldMap (_ wrapperOfA pred)
-- Found hole ‘_’ with type: (a0 -> Bool -> f0 a0) -> (a -> Bool) -> a -> f a
-- Where: ‘a’ is a rigid type variable bound by the type signature for interactive:IHaskell136.filterF :: (Applicative f, Foldable t, Monoid (f a)) => (a -> Bool) -> t a -> f a at :1:12
-- ‘f’ is a rigid type variable bound by the type signature for interactive:IHaskell136.filterF :: (Applicative f, Foldable t, Monoid (f a)) => (a -> Bool) -> t a -> f a at :1:12
-- ‘a0’ is an ambiguous type variable
-- ‘f0’ is an ambiguous type variable
-- Relevant bindings include
-- pred :: a -> Bool (bound at :2:9)
-- filterF :: (a -> Bool) -> t a -> f a (bound at :2:1)
-- In the expression: _
-- In the first argument of ‘foldMap’, namely ‘(_ wrapperOfA pred)’
-- In the expression: foldMap (_ wrapperOfA pred)
Basically, wrapperOfA does not look like f (a -> b) as <*> would imply, nor does pred look like type f a. Yet it works and type checks - why?
The (<*>) there uses the Applicative instance for functions. In...
-- Writing it infix, for the sake of clarity.
filterF pred = foldMap (wrapperOfA <*> pred)
... wrapperOfA has type a -> (Bool -> f a), and pred has type a -> Bool. That being so, wrapperOfA <*> pred has type a -> f a, as expected. If we substitute the implementation of (<*>) for functions (see the question linked to above for details), we get...
filterF pred = foldMap (\a -> wrapperOfA a (pred a))
... which makes it clear what is going on.
<*> uses the Applicative instance for functions
(<*>) :: f (a -> b) -> f a -> f b
where f is a (->) r , namely a function from the r domain.
Substituting, the first argument of <*> becomes a function from the r domain AND the a domain, then returning a b (a function of 2 arguments, since type r -> (a -> b) is equivalent to r -> a -> b), and the second argument becomes a function from the r domain returning an a.
To produce a (->) r b, we should apply the second-argument (a function) to the r parameter, and the resulting a is passed as a second argument to the thing in front of <*>. That is,
(<*>) wrapperOfA pred r = wrapperOfA r (pred r)
This leads me to a follow-up question/comment to bring the focus to foldMap and filterF which I now rename filterH.
filterH :: (a -> Bool) -> t a -> h a
foldMap :: (a -> f a) -> t a -> f a
wrapperOfA <*> pred :: a -> h a
where h is any applicative and monoid with corresponding pure and mempty but is as yet undefined. So I needed to request a return type eg ::[Int] in order for it to compile&evaluate. Can filterH be used without having to specify my own type h? Am I missing something in this solution?
This is a question from the textbook "haskell programming from first principles", in the foldables section.
Maybe you'll find easier this solution:
import Control.Conditional (select)
filterF :: (Applicative f, Foldable t, Monoid (f a)) => (a -> Bool) -> t a -> f a
filterF f = foldMap (select f pure mempty)
Here, select is just a functional if-then-else, where you provide functions for the condition, the true case and the else case.

Haskell: need to understand signature of Functor

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.

Haskell lenses: how to make view play nicely with traverse?

I am trying to learn about lenses by implementing it in Haskell. I have implemented the view combinator as follows:
{-# LANGUAGE RankNTypes #-}
import Control.Applicative
import Data.Traversable
type Lens s a = Functor f => (a -> f a) -> s -> f s
view :: Lens s a -> s -> a
view lens = getConst . lens Const
However when I try to use it in conjunction with traverse I get the following error message:
Prelude> :load Lens.hs
[1 of 1] Compiling Main ( Lens.hs, interpreted )
Ok, modules loaded: Main.
*Main> :t view traverse
<interactive>:1:6:
Could not deduce (Applicative f) arising from a use of ‘traverse’
from the context (Traversable t)
bound by the inferred type of it :: Traversable t => t a -> a
at Top level
or from (Functor f)
bound by a type expected by the context:
Functor f => (a -> f a) -> t a -> f (t a)
at <interactive>:1:1-13
Possible fix:
add (Applicative f) to the context of
a type expected by the context:
Functor f => (a -> f a) -> t a -> f (t a)
or the inferred type of it :: Traversable t => t a -> a
In the first argument of ‘view’, namely ‘traverse’
In the expression: view traverse
Unfortunately, I don't understand this error message. Please explain what it means and how I may fix it.
As the other answers already explain, the issue is that view expects something that works for any Functor f, but traverse only works if f is also Applicative (and there are functors which are not applicative).
In lens, the problem is solved by making the type of view not take a Rank2 argument (in fact, most functions in lens don't use the Lens type synonym, they always use something weaker). For your function, observe that view only ever uses f ~ Const. This is why you can change the type signature to:
view :: ((a -> Const a a) -> s -> Const a s) -> s -> a
The implementation can stay the same, but now view also works on traverse:
view traverse :: (Traversable t, Monoid a) => t a -> a
Note the extra Monoid constraint. This constraint appears because if you set f ~ Const a in traverse :: (Traversable t, Applicative f) => (a -> f a) -> t a -> f (t a), you need an instance Applicative (Const a). That instance has a Monoid constraint on a though. And this also makes sense, because the traversable might be empty or contain more than one element, so you need mempty and mappend.
tl;dr - According to your definition of Lens, a traverse cannot be a Lens because traverse doesn't work for all Functors.
Let's take a look at your types:
λ :set -XRankNTypes
λ :m +Control.Applicative Data.Traversable
λ type Lens s a = Functor f => (a -> f a) -> s -> f s
λ :t traverse
traverse
:: (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)
Now at this point we can see that traverse is, in one way, slightly more general than our Lens type - it can take a function
from a -> f b where our lens can only take functions from a -> f a.
Restricting it to that case is no problem, so we can say
λ :t traverse :: (Traversable t, Applicative f) => (a -> f a) -> t a -> f (t a)
traverse :: (Traversable t, Applicative f) => (a -> f a) -> t a -> f (t a)
:: (Applicative f, Traversable t) => (a -> f a) -> t a -> f (t a)
So now it's obvious that if traverse is to be a Lens, it must be a Lens (t a) a, since that's the only way to make the type variables line up.
So let's try that out.
λ :t traverse :: Lens (t a) a
<interactive>:1:1:
Could not deduce (Traversable t1) arising from a use of `traverse'
from the context (Functor f)
bound by the inferred type of
it :: Functor f => (a -> f a) -> t a -> f (t a)
at Top level
or from (Functor f1)
bound by an expression type signature:
Functor f1 => (a1 -> f1 a1) -> t1 a1 -> f1 (t1 a1)
at <interactive>:1:1-24
Possible fix:
add (Traversable t1) to the context of
an expression type signature:
Functor f1 => (a1 -> f1 a1) -> t1 a1 -> f1 (t1 a1)
or the inferred type of
it :: Functor f => (a -> f a) -> t a -> f (t a)
In the expression: traverse :: Lens (t a) a
Oof, it didn't like that. Oh, wait, in order to use traverse our type t has to be Traversable, so let's add that restriction. (Just like the "Possible fix") suggests:
λ :t traverse :: Traversable t => Lens (t a) a
<interactive>:1:1:
Could not deduce (Applicative f1) arising from a use of `traverse'
from the context (Functor f, Traversable t)
bound by the inferred type of
it :: (Functor f, Traversable t) => (a -> f a) -> t a -> f (t a)
at Top level
or from (Traversable t1, Functor f1)
bound by an expression type signature:
(Traversable t1, Functor f1) =>
(a1 -> f1 a1) -> t1 a1 -> f1 (t1 a1)
at <interactive>:1:1-41
Possible fix:
add (Applicative f1) to the context of
an expression type signature:
(Traversable t1, Functor f1) =>
(a1 -> f1 a1) -> t1 a1 -> f1 (t1 a1)
or the inferred type of
it :: (Functor f, Traversable t) => (a -> f a) -> t a -> f (t a)
In the expression: traverse :: Traversable t => Lens (t a) a
Ok, so the problem now is that it can't infer that f is Applicative (which is also required to use traverse), just that it's a Functor (which it gets from the definition of Lens).
We can't add Applicative f to the context though - the f is hidden. When we say type Lens s a = Functor f => (a -> f a) -> s -> f s, we're saying that the Lens has to work for all Functors.
But traverse only works for the subset of Functors that are also Applicative. So in this way the type of traverse is more specific than is allowed for Lenses.
traverse has this type:
traverse :: (Applicative f, Traversable t) => (x -> f y) -> t x -> f (t y)
If we make the free variable f in the type definition of Lens explicit, its definition is actually
type Lens s a = forall f . Functor f => (a -> f a) -> s -> f s
So view wants a function that can operate on any Functor, whereas traverse can only operate on an Applicative.
You can fix the error simply by changing Functor into Applicative in the definition of Lens, but I'm not sure if that's exactly what you would want to achieve here.

Resources