I'm trying to understand what the functors are, but so far I can't. What's the difference between these 2:
Prelude> fmap (+1) [1..9]
[2,3,4,5,6,7,8,9,10]
Prelude> map (+1) [1..9]
[2,3,4,5,6,7,8,9,10]
For lists, there is no difference, map is just fmap specialised to lists.
fmap has a more general type:
fmap :: Functor f => (a -> b) -> f a -> f b
this means it can be used with any functor e.g.
fmap (+ 3) (Just 4) -- Just 7
fmap (+ 4) (+ 3) 1 -- 8. Functions are functors where fmap = (.)
fmap read getLine :: IO Int -- IO is a functor
while map has type
map :: (a -> b) -> [a] -> [b]
If you look at the source, the functor instance for lists defines fmap as map:
instance Functor [] where
fmap = map
Related
I am new to Haskell. This may be stupid question.
As the Applicative typeclass has apply function that takes the functions and data in the same context. Why can't it be different and be more generic.
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Why can't we write something like this
class Functor f => Applicative f where
(<*>) :: Functor g => g (a -> b) -> f a -> g (f b)
(<*>) gab fa = fmap (\g -> fmap g fa) gab
(<<*>>) :: Functor g => (g (f a) -> f a) -> g (a -> b) -> f a -> f b
(<<*>>) peelOuter gab fa = peelOuter $ gab <*> fa
(>>*<<) :: Functor g => (g (f a) -> g a) -> g (a -> b) -> f a -> g b
(>>*<<) cleanInner gab fa = cleanInner $ gab <*> fa
It can be used as below
-- Extract List from maybe
elfm :: Maybe [a] -> [a]
elfm Nothing = []
elfm (Just xs) = xs
-- Fuse List elements in Maybe []
flem :: Monoid a => Maybe [a] -> Maybe a
flem Nothing = mempty
flem (Just xs) = Just $ foldl (<>) mempty xs
Just (*2) <*> [1,2,3,4]
-- Just [2,4,6,8]
(<<*>>) elfm (Just (*2)) [1,2,3,4]
-- [2,4,6,8]
(>>*<<) flem (Just (++ "Haskell")) ["Hello, "]
-- Just "Hello, Haskell"
And I read that the whole point of having Applicatives is the drawback of Functors lifting multi argument functions. Is this right?
And I don't think the function application is as expected.
add :: Num a => a -> a -> a
add a b = a + b
-- I want to apply [1,2,3] as First arguments and [4,5,6] as 2nd arguments.
-- Like add 1 4, add 2 4, add 3 6
-- But it is give all possibilities of combinations like a tree
-- <*>
-- (+1) (+2) (+3)
-- (1+4)(1+5)(1+6) (2+4)(2+5)(2+6) (3+4)(3+5)(3+6)
And also they are compared to batch processing, but no quite real life example is given. Please provide an example for this.
Each instance of Applicative necessarily has its own implementation of <*>. That's why we have type classes in the first place. Your code has all the methods defined in the class itself, nothing is left for instances. This means there isn't much of a type class at all. There's just a bunch of generic functions. All the meat is delegated to the arguments peelOuter and cleanInner of ('<<*>>) and (>>*<<). Let's look at them more closely. They are more or less symmetrical so (<<*>>) should be enough.
(<<*>>) :: Functor g => (g (f a) -> f a) -> g (a -> b) -> f a -> f b
(<<*>>) peelOuter gab fa = peelOuter $ gab <*> fa
It's actually peelOuter that should have been a method of a type class, but there is more than one problem with that.
The first problem that there are two functors involved, and peelOuter needs to be implemented separately for each pair of functors. That is, we would have a bi-parametric type class ApplicativePair here, and we would need a separate instance for each pair.
The second problem is that peelOuter cannot be implemented for every pair of bona fide Applicative functors. One cannot extract an Id a from a Maybe (Id a), or a [a] from an IO [a], or ...
Worse yet, it isn't clear if it is always implementable when f and g are the same functor. Clearly, when f is a monad, then it's just a join. Not all applicatives are monads however, and join is precisely what an applicative lacks to be a monad. So peelOuter, even if such a type is implementable, would violate some monad laws. Is that a bad thing? Not necessarily, if it still follows applicative laws. You however have not supplied any laws, only a bunch of functions.
Any two functors are Functor and Applicative functors. This coded with newtype Compose, see Data.Functor.Compose.
So, your examples can be solved by newtype Compose.
-- Just (*2) <*> [1,2,3,4]
getCompose $ pure (*2) <*> Compose (Just [1,2,3,4])
-- or
getCompose $ (*2) <$> Compose (Just [1,2,3,4])
-- Just [2,4,6,8]
-- (<<*>>) elfm (Just (*2)) [1,2,3,4]
elfm . getCompose $ pure (*2) <*> Compose (Just [1,2,3,4])
-- or with toList (method of Foldable)
toList $ pure (*2) <*> Compose (Just [1,2,3,4])
-- or
toList $ (*2) <$> Compose (Just [1,2,3,4])
-- [2,4,6,8]
-- (>>*<<) flem (Just (++ "Haskell")) ["Hello, "]
flem . getCompose $ pure (++ "Haskell") <*> Compose (Just ["Hello, "])
-- or with toList and listToMaybe
listToMaybe . toList $ pure (++ "Haskell") <*> Compose (Just ["Hello, "])
-- or
listToMaybe . toList $ (++ "Haskell") <$> Compose (Just ["Hello, "])
-- or with head :: Foldable f => f a -> Maybe a
head $ (++ "Haskell") <$> Compose (Just ["Hello, "])
-- Just "Hello, Haskell"
About the last question. You have got an answer in comments by #Robin Zigmond. It wrote about the newtype ZipList. With ZipList you can do:
getZipList $ (+) <$> ZipList [1,2,3] <*> ZipList [4,5,6]
-- [5,7,9]
So, one of the purposes of newtype in Haskell is the ability to write different instances for some type.
I have a list of functions of type a -> b -> Bool, and am trying to apply them to two inputs and combine the results with All or Any. I have this working with functions of one variable:
mconcat (map (All . ) [(<7),(>7),(==7)]) $ 6
but I cannot figure out how to do the same with two variable functions.
This works:
mconcat (map (All . ) (map (uncurry) [(<),(>),(==)])) $ (,) 6 7
but it looks to me like an ugly workaround.
Is there a better way to do this?
This is the sort of code that writes itself - you just have to make the types join up. But there are a couple of standard tools (namely Applicative and Traversable) which you can use to make your code shorter.
In the Data.Traversable module lives sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a). When specialised to []'s instance of Traversable and the function applicative (->) r we get:
sequenceA :: [r -> a] -> r -> [a]
So sequenceA yanks -> out of [], applying each function in the list to a fixed argument.
sequenceA [(< 7), (> 7), (== 7)] :: (Num n, Ord n) => n -> [Bool]
-- equivalent to:
\n -> map ($ n) [(< 7), (> 7), (== 7)]
So your first function can be written as
f :: (Num n, Ord n) => n -> Bool
f = and . sequenceA [(< 7), (> 7), (== 7)]
I'm using and instead of mconcat . map (All .).
For your second function, uncurry is the right tool. We have to map uncurry over the list of binary functions to get a list of unary functions of tuples, so that we can hoist the single argument out using sequenceA. Because traverse f = sequenceA . map f we can write it as:
g :: Ord n => n -> n -> Bool
g = curry $ and . traverse uncurry [(<), (>), (==)]
(NB, for any correctly-implemented instance of Ord, > and < should be mutually exclusive. So both of these functions will always return False.)
A close alternative to the original code:
mconcat (map (\f a b -> All (f a b)) [(<),(<=)]) 3 4
One can further rewrite \f a b -> All (f a b) in pointless style:
mconcat (map ((.) (All .)) [(<),(<=)]) 3 4
I am having some trouble understanding how the function instance (->) r of Applicative works in Haskell.
For example if I have
(+) <$> (+3) <*> (*100) $ 5
I know you get the result 508, I sort of understand that you take the result of (5 + 3) and (5 * 100) and you apply the (+) function to both of these.
However I do not quite understand what is going on. I assume that the expression is parenthesized as follows:
((+) <$> (+3)) <*> (*100)
From my understanding what is happening is that your mapping (+) over the eventual result of (+3) and then you are using the <*> operator to apply that function to the eventual result of (*100)
However I do not understand the implementation of <*> for the (->) r instance and why I cannot write:
(+3) <*> (*100)
How does the <*>, <$> operator work when it comes to (->) r?
<$> is just another name for fmap and its definition for (->) r is (.) (the composition operator):
intance Functor ((->) r) where
fmap f g = f . g
You can basically work out the implementation for <*> just by looking at the types:
instance Applicative ((->) r) where
(<*>) :: (r -> a -> b) -> (r -> a) -> (r -> b)
f <*> g = \x -> f x (g x)
You have a function from r to a to b and a function from r to a. You want a funtion from r to b as a result. First thing you know is you return a function:
\x ->
Now you want to apply f since it is the only item which may return a b:
\x -> f _ _
Now the arguments for f are of type r and a. r is simply x (since it alrady is of type r and you can get an a by applying g to x:
\x -> f x (g x)
Aaand you're done. Here's a link to the implementation in Haskell's Prelude.
Consider the type signature of <*>:
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Compare this to the type signature for ordinary function application, $:
($) :: (a -> b) -> a -> b
Notice that they are extremely similar! Indeed, the <*> operator effectively generalizes application so that it can be overloaded based on the types involved. This is easy to see when using the simplest Applicative, Identity:
ghci> Identity (+) <*> Identity 1 <*> Identity 2
Identity 3
This can also be seen with slightly more complicated applicative functors, such as Maybe:
ghci> Just (+) <*> Just 1 <*> Just 2
Just 3
ghci> Just (+) <*> Nothing <*> Just 2
Nothing
For (->) r, the Applicative instance performs a sort of function composition, which produces a new function that accepts a sort of “context” and threads it to all of the values to produce the function and its arguments:
ghci> ((\_ -> (+)) <*> (+ 3) <*> (* 100)) 5
508
In the above example, I have only used <*>, so I’ve explicitly written out the first argument as ignoring its argument and always producing (+). However, Applicative typeclass also includes the pure function, which has the same purpose of “lifting” a pure value into an applicative functor:
ghci> (pure (+) <*> (+ 3) <*> (* 100)) 5
508
In practice, though, you will rarely see pure x <*> y because it is precisely equivalent to x <$> y by the Applicative laws, since <$> is just an infix synonym for fmap. Therefore, we have the common idiom:
ghci> ((+) <$> (+ 3) <*> (* 100)) 5
508
More generally, if you see any expression that looks like this:
f <$> a <*> b
…you can read it more or less like the ordinary function application f a b, except in the context of a particular Applicative instance’s idioms. In fact, an original formulation of Applicative proposed the idea of “idiom brackets”, which would add the following as syntactic sugar for the above expression:
(| f a b |)
However, Haskellers seem to be satisfied enough with the infix operators that the benefits of adding the additional syntax has not been deemed worth the cost, so <$> and <*> remain necessary.
Let's take a look at the types of these functions (and the definitions that we automatically get along with them):
(<$>) :: (a -> b) -> (r -> a) -> r -> b
f <$> g = \x -> f (g x)
(<*>) :: (r -> a -> b) -> (r -> a) -> r -> b
f <*> g = \x -> f x (g x)
In the first case, <$>, is really just function composition. A simpler definition would be (<$>) = (.).
The second case is a little more confusing. Our first input is a function f :: r -> a -> b, and we need to get an output of type b. We can provide x :: r as the first argument to f, but the only way we can get something of type a for the second argument is by applying g :: r -> a to x :: r.
As an interesting aside, <*> is really the S function from SKI combinatory calculus, whereas pure for (-> r) is the K :: a -> b -> a (constant) function.
As a Haskell newbie myself, i'll try to explain the best way i can
The <$> operator is the same as mapping a function on to another function.
When you do this:
(+) <$> (+3)
You are basically doing this:
fmap (+) (+3)
The above will call the Functor implementation of (->) r which is the following:
fmap f g = (\x -> f (g x))
So the result of fmap (+) (+3) is (\x -> (+) (x + 3))
Note that the result of this expression has a type of a -> (a -> a)
Which is an applicative! That is why you can pass the result of (+) <$> (+3) to the <*> operator!
Why is it an applicative you might ask? Lets look the at the <*> definition:
f (a -> b) -> f a -> f b
Notice that the first argument matches our returned function definition a -> (a -> a)
Now if we look at the <*> operator implementation, it looks like this:
f <*> g = (\x -> f x (g x))
So when we put all those pieces together, we get this:
(+) <$> (+3) <*> (+5)
(\x -> (+) (x + 3)) <*> (+5)
(\y -> (\x -> (+) (x + 3)) y (y + 5))
(\y -> (+) (y + 3) (y + 5))
The (->) e Functor and Applicative instances tend to be a bit confusing. It may help to view (->) e as an "undressed" version of Reader e.
newtype Reader e a = Reader
{ runReader :: e -> a }
The name e is supposed to suggest the word "environment". The type Reader e a should be read as "a computation that produces a value of type a given an environment of type e".
Given a computation of type Reader e a, you can modify its output:
instance Functor (Reader e) where
fmap f r = Reader $ \e -> f (runReader r e)
That is, first run the computation in the given environment, then apply the mapping function.
instance Applicative (Reader e) where
-- Produce a value without using the environment
pure a = Reader $ \ _e -> a
-- Produce a function and a value using the same environment;
-- apply the function to the value
rf <*> rx = Reader $ \e -> (runReader rf e) (runReader rx e)
You can use the usual Applicative reasoning for this as any other applicative functor.
Currently reading through this article (which is pretty brilliant btw) and have a pretty simple question:
If I combine two functions like (+3) and (+2) with <$>, it seems to give me a new function that adds 5 to whatever is passed to it. If I do the same with the function composition operator, i.e. (+3) . (+2), would it not do the same thing? If that is true, is there a relationship here between these two operators such that they do the same thing in this simple case?
Is this even an intelligent question?
The functions fmap and <$> both have the same type:
> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
> :t (<$>)
(<$>) :: Functor f => (a -> b) -> f a -> f b
While the function . is
> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
So how is it possible that we can use fmap on a function and end up with .? I'm assuming you understand what a Functor is, so now you have to understand that "functions" are Functors. How so?
> :i (->)
data (->) a b -- Defined in `GHC.Prim'
instance Monad ((->) r) -- Defined in `GHC.Base'
instance Functor ((->) r) -- Defined in `GHC.Base'
instance Applicative ((->) a) -- Defined in `Control.Applicative'
Unlike Just, [] and Left, functions do not have a constructor that can be used. The Functor instance is applied to the syntax itself. We can see from :info in ghci that the syntactic arrow -> actually has an instance for functor.
What happens when we look at the type of +3?
> :t (+3)
(+3) :: Num a => a -> a
So the function (+3) is a Functor that accepts an a and returns an a. When we use fmap on a Functor and that also gives us back a Functor, we get nested Functors:
> :t fmap Just (Just 3)
fmap Just (Just 3) :: Num a => Maybe (Maybe a)
> :t fmap (replicate 5) [1,2,3]
fmap (replicate 5) [1,2,3] :: Num a => [[a]]
Likewise, when we apply fmap to two functions we get a function inside a function. The only difference is that they are fused together:
> :t (fmap (+3) (+2))
(fmap (+3) (+2)) :: Num a => a -> a
Why doesn't this result in the type (->) (->) a a? We have to remember that the first argument of fmap is a function (a -> b) and not necessarily a Functor. So when we do fmap g (Just 5) we can have any transformation. But whenever we perform fmap on a function we know that it will always result with a function inside of a function.
Thus fmap (+3) (+2) evaluates to something like this: \x -> (\x' -> x' + 3) (x + 2). That is a really roundabout way of writing (+3) . (+2).
> :t (fmap (+3) (+2))
(fmap (+3) (+2)) :: Num a => a -> a
> :t ((.) (+3) (+2))
((.) (+3) (+2)) :: Num a => a -> a
Normally to get around the concat problem (Maybe (Maybe a)) or [[a]] we actually need to rely on it being a Monad a, so that we can use a bind >>=. But functions (->) are a special case because we know that every single time we use fmap on a function, it will always give us a function in side of a function. This cannot be said for any other Functor except ->. As such we can be sure to always concatenate fmap on functions.
Therefore any f <$> g == f . g
Edit: A quick side note, if you do this fmap (+) (+0) you end up with a function inside a function. In this case the monadic bind (>>=) is actually needed to concatenate the functions:
> :t fmap (+) (+0)
fmap (+) (+0) :: Num a => a -> a -> a
> :t (+0) >>= (+)
(+0) >>= (+) :: Num b => b -> b
> let bindfunc = (+0) >>= (+)
> bindfunc 5
10
Which is not entirely unlike the behaviour we get when we do [1,2] >>= replicate 5:
> [1,2] >>= replicate 5
[1,1,1,1,1,2,2,2,2,2]
To find information about the Functor instance for functions, match up the types to find the relevant instance:
fmap :: (a -> b) -> f a -> f b
Then here a ~ Int, b ~ Int and f ~ (->) Int.
You can see all of the Functor instances that come with GHC here. (->) is just an infix type operator with two type parameters. We usually see it applied as Int -> Int, but this is equivalent to (->) Int Int.
There is a Functor instance for the (partially applied) type (->) r (for any type r::*).
Looking at the ((->) r) instance for Functor, we see that fmap = (.), so there is no practical difference between (+3) . (+2) and fmap (+3) (+2) (same as (+3) <$> (+2).
Learn You a Haskell offers the following exercise:
Let's try implementing a function that takes a list of applicatives and
returns an applicative that has a list as its result value.
LYAH gives the type signature sequenceA' :: (Applicative f) => [f a] -> f [a]
I started with Applicative, but wasn't sure how to extract a from f a in a general way for all Applicative's.
So, I implemented it as a Maybe. Of course this is unacceptable for all `Applicative's.
import Control.Applicative
sequenceA' :: (Num a) => [Maybe a] -> Maybe [a]
sequenceA' [] = pure []
sequenceA' xs = pure $ [extract' x | x <- xs ]
extract' :: (Num a) => Maybe a -> a
extract' x = case x of
Just y -> y
Nothing -> 0
How can I extract a from f a where f is an Applicative?
You can't in general. In fact, the Maybe example you gave is a good example of why since it requires it to be a Num instance. It wouldn't make sense for the Maybe Applicative in general, so that would be a counterexample to a general solution. Another counterexample would be IO. There is no valid extract implementation for IO.
To make a function that is general enough to work with all Applicative instances, you must be able to construct the function using only methods from Applicative and its super-class, Functor. There is no way to make extract using only fmap, pure and (<*>).
It's not necessary to take things out of the applicative functor to achieve this.
The great thing about applicative functors is they allow you to use ordinary functions on the results of each applicative computation, so
if you have applicatives c1, c2 and c3 of types f a, f b, f c
that produce values v1, v2 and v3 of types a, b and c,
but you actually want to use a function g :: a -> b -> c -> d on the values
to produce g v1 v2 v3 :: d, then you can do
g <$> c1 <*> c2 <*> c3
which has type f d.
So we can use the function (:) to join the first value out of our list of applicatives with the rest of them, so you can do someytthing like (:) <$> thingThatGivesFirstValue <*> thing that gives the rest of the list. So it'll be a nice recursion if you pattern match on the list of applicatives.
sequenceA' :: (Applicative f) => [f a] -> f [a]
sequenceA' [] = -- just give the empty list
sequenceA' (c:cs) = -- hmm. What could go here then?
so for example you should get
ghci> sequenceA' [getLine, getLine, getLine]
Hello
there
everyone
["Hello","there","everyone"]
ghci> sequenceA' [Just 3, Just 4, Just 5]
Just [3,4,5]
Here's an example function to help you along with the recursice case:
nth :: Applicative f => f Int -> f [a] -> f a
nth wrappedInt wrappedList = (!!) <$> wrappedInt <*> wrappedList
So you don't need to unwrap anything or get values out, the operators<$> and <*> let you do what you like inside.
nth (Just 3) (Just "Hello") == 'l'
Here's a hint:
foo :: Applicative f => f Int -> f Int -> f Int
foo fx fy = (+) <$> fx <*> fy -- apply + "under" the functor
bar :: Applicative f => f a -> f [a] -> f [a]
bar fx fxs = ??? <$> fx <*> fxs -- apply ??? "under" the functor
sequenceA' :: Applicative f => [f a] -> f [a]
sequenceA' [] = pure [] -- as in your solution
sequenceA' (x:xs) = let y = x -- :: f a
ys = sequenceA' xs -- :: f [a]
in ???
I use let in the last function to clarify the types which are involved. After you fill in the ??? you can of course remove the let.
You can extract a from f a with pattern matching or evaluation, if f is not IO
import Control.Applicative
import System.IO
import Control.Monad.ST
-- with AndrewC sequenceA' definition
sequenceA' :: (Applicative f) => [f a] -> f [a]
sequenceA' [] = pure []
sequenceA' (c:cs) = (:) <$> c <*> sequenceA' cs
seqOfMaybes :: [Maybe a] -> [a]
seqOfMaybes listOfMb = case sequenceA' listOfMb of
Nothing -> []
Just list -> list
-- sequencing ST computations
compute :: a -> ST s a
compute x = return x
seqOfSTData :: [Int] -> [Int]
seqOfSTData vals = runST $ (sequenceA' (map compute vals) :: ST s [Int])
-- but you cannot escape the applicative f if f is IO
readAnInt :: IO Int
readAnInt = putStrLn "give me an Int>" >> hFlush stdout >> getLine >>= (return . read)
seqOfIO :: [IO a] -> IO [a]
seqOfIO listOfIO = sequenceA' listOfIO
main :: IO ()
main = do
print $ seqOfMaybes [Just 3, Just 4, Just 5]
print $ seqOfSTData [1,2,3]
seqOfIO [readAnInt, readAnInt] >>= print