For a List, why does right apply (*>) behave as repeating and appending the second argument n times, where n is the length of the first argument?
ghci> [1,2,3] *> [4,5]
[4,5,4,5,4,5]
The *> operator is defined, by default, as
xs *> ys = id <$ xs <*> ys
which in turn translates, by default, to
const id <$> xs <*> ys
That is, it replaces each element of xs with id to get xs' and then calculates xs' <*> ys. [] is a Monad instance, where (=<<) = concatMap. One of the laws of Applicative lays out the relationship between Applicative and Monad instances:
pure = return
fs <*> as = fs `ap` as = fs >>= \f -> as >>= \a -> f a
For lists, this is
fs <*> as = [f a | f <- fs, a <- as]
So *> for lists is ultimately determined by the Monad instance.
Note that there is another very sensible Applicative instance for lists, which is made available through a newtype in Control.Applicative:
newtype ZipList a = ZipList [a]
instance Applicative ZipList where
pure = repeat
(<*>) = zipWith ($)
Related
Excersize from an online course.
Suppose, that for a standard list Applicative functor the <*> operator is defined in a standard way, while pure is changed to
pure x = [x,x]
What laws of Applicative typeclass will be violated?
Homomorphism: pure g <*> pure x ≡ pure (g x)
Identity: pure id <*> xs ≡ xs
Interchange: fs <*> pure x ≡ pure ($ x) <*> fs
Applicative-Functor: g <$> xs ≡ pure g <*> xs
Composition: (.) <$> us <*> vs <*> xs ≡ us <*> (vs <*> xs)
I created the following file:
newtype MyList a = MyList {getMyList :: [a]}
deriving Show
instance Functor MyList where
fmap f (MyList xs) = MyList (map f xs)
instance Applicative MyList where
pure x = MyList [x,x]
MyList gs <*> MyList xs = MyList ([g x | g <- gs, x <- xs])
fs = MyList [\x -> 2*x, \x -> 3*x]
xs = MyList [1,2]
x = 1
g = (\x -> 2*x)
us = MyList [(\x -> 2*x)]
vs = MyList [(\x -> 3*x)]
Then I tried:
Homomorphism: pure g <*> pure x ≡ pure (g x)
*Main> pure g <*> pure x :: MyList Integer
MyList {getMyList = [2,2,2,2]}
*Main> pure (g x) :: MyList Integer
MyList {getMyList = [2,2]}
Identity: pure id <*> xs ≡ xs
*Main> pure id <*> xs :: MyList Integer
MyList {getMyList = [1,2,1,2]}
*Main> xs :: MyList Integer
MyList {getMyList = [1,2]}
Interchange: fs <*> pure x ≡ pure ($ x) <*> fs
*Main> fs <*> pure x
[2,3]
*Main> pure ($ x) <*> fs
[2,3]
Applicative-Functor: g <$> xs ≡ pure g <*> xs
*Main> g <$> xs
MyList {getMyList = [2,4]}
*Main> pure g <*> xs
MyList {getMyList = [2,4,2,4]}
Composition: (.) <$> us <*> vs <*> xs ≡ us <*> (vs <*> xs)
*Main> (.) <$> us <*> vs <*> xs
MyList {getMyList = [6,12]}
*Main> us <*> (vs <*> xs)
MyList {getMyList = [6,12]}
Composition shouldn't be violated, because pure is not used here.
It seems that Homomorphism, Identity and Applicative-Functor don't work. But when I select them in the course, it says that the answer is wrong. So, who is the fool: me or the author of the course?
As per #DavidFletcher's comment, using your code, I see different output for the interchange test:
> fs <*> pure x
MyList {getMyList = [2,2,3,3]}
> pure ($ x) <*> fs
MyList {getMyList = [2,3,2,3]}
so you might want to double-check that one.
Haskell has Functor, Applicative and Monad instances defined for functions (specifically the partially applied type (->) a) in the standard library, built around function composition.
Understanding these instances is a nice mind-bender exercise, but my question here is about the practical uses of these instances. I'd be happy to hear about realistic scenarios where folks used these for some practical code.
A common pattern that involves Functor and Applicative instances of functions is for example (+) <$> (*2) <*> (subtract 1). This is particularly useful when you have to feed a series of function with a single value. In this case the above is equivalent to \x -> (x * 2) + (x - 1). While this is very close to LiftA2 you may extend this pattern indefinitely. If you have an f function to take 5 parameters like a -> a -> a -> a -> a -> b you may do like f <$> (+2) <*> (*2) <*> (+1) <*> (subtract 3) <*> (/2) and feed it with a single value. Just like in below case ;
Prelude> (,,,,) <$> (+2) <*> (*2) <*> (+1) <*> (subtract 3) <*> (/2) $ 10
(12.0,20.0,11.0,7.0,5.0)
Edit: Credit for a re-comment of #Will Ness for a comment of mine under another topic, here comes a beautiful usage of applicative over functions;
Prelude> let isAscending = and . (zipWith (<=) <*> drop 1)
Prelude> isAscending [1,2,3,4]
True
Prelude> isAscending [1,2,5,4]
False
Sometimes you want to treat functions of the form a -> m b (where m is an Applicative) as Applicatives themselves. This often happens when writing validators, or parsers.
One way to do this is to use Data.Functor.Compose, which piggybacks on the Applicative instances of (->) a and m to give an Applicative instance for the composition:
import Control.Applicative
import Data.Functor.Compose
type Star m a b = Compose ((->) a) m b
readPrompt :: Star IO String Int
readPrompt = Compose $ \prompt -> do
putStrLn $ prompt ++ ":"
readLn
main :: IO ()
main = do
r <- getCompose (liftA2 (,) readPrompt readPrompt) "write number"
print r
There are other ways, like creating your own newtype, or using ready-made newtypes from base or other libraries.
here an application of the bind function that I used for solving the Diamond Kata. Take a simple function that mirrors its input discarding the last element
mirror :: [a] -> [a]
mirror xs = xs ++ (reverse . init) xs
let's rewrite it a bit
mirror xs = (++) xs ((reverse . init) xs)
mirror xs = flip (++) ((reverse . init) xs) xs
mirror xs = (reverse . init >>= flip (++)) xs
mirror = reverse . init >>= flip (++)
Here is my complete implementation of this Kata: https://github.com/enolive/exercism/blob/master/haskell/diamond/src/Diamond.hs
I'm new to Haskell and trying to understand how does this work?
sequenceA [(+3),(+2),(+1)] 3
I have started from the definition
sequenceA :: (Applicative f) => [f a] -> f [a]
sequenceA [] = pure []
sequenceA (x:xs) = (:) <$> x <*> sequenceA xs
And then unfolded recursion into this
(:) <$> (+3) <*> $ (:) <$> (+2) <*> $ (:) <$> (+1) <*> pure []
(:) <$> (+3) <*> $ (:) <$> (+2) <*> $ (:) <$> (+1) <*> []
But here i don't understand for which applicative functor operator <*> will be called, for ((->) r) or for []
(:) <$> (+1) <*> []
Can somebody go step by step and parse sequenceA [(+3),(+2),(+1)] 3 step by step? Thanks.
This can be seen from the type of sequenceA:
sequenceA :: (Applicative f, Traversable t) => t (f a) -> f (t a)
The argument's outer type has to be a Traverable, and its inner type has to be Applicative.
Now, when you give sequenceA a list of functions (Num a) => [a -> a] the list will be the Traversable, and the things inside the list should be Applicative. Therefore, it uses the applicative instance for functions.
So when you apply sequenceA to [(+3),(+2),(+1)], the following computation is built:
sequenceA [(+3),(+2),(+1)] = (:) <$> (+3) <*> sequenceA [(+2),(+1)]
sequenceA [(+2),(+1)] = (:) <$> (+2) <*> sequenceA [(+1)]
sequenceA [(+1)] = (:) <$> (+1) <*> sequenceA []
sequenceA [] = pure []
Let's look at the last line. pure [] takes an empty list and puts it inside some applicative structure. As we've just seen, the applicative structure in this case is ((->) r). Because of this, sequenceA [] = pure [] = const [].
Now, line 3 can be written as:
sequenceA [(+1)] = (:) <$> (+1) <*> const []
Combining functions this way with <$> and <*> results in parallel application. (+1) and const [] are both applied to the same argument, and the results are combined using (:)
Therefore sequenceA [(+1)] returns a function that takes a Num a => a type value, applies (+1) to it, and then prepends the result to an empty list, \x -> (:) ((1+) x) (const [] x) = \x -> [(+1) x].
This concept can be extended further to sequenceA [(+3), (+2), (+1)]. It results in a function that takes one argument, applies all three functions to that argument, and combines the three results with (:) collecting them in a list: \x -> [(+3) x, (+2) x, (+1) x].
it is using instance Applicative ((->) a).
Try this in ghci:
Prelude> :t [(+3),(+2),(+1)]
[(+3),(+2),(+1)] :: Num a => [a -> a]
Prelude> :t sequenceA
sequenceA :: (Applicative f, Traversable t) => t (f a) -> f (t a)
and pattern match the argument type: t = [], f = (->) a
and the Applicative constraint is on f.
For anyone who has trouble accepting that an argument to sequenceA [(+1)] just magically applies itself to BOTH (+1) and const [], this is for you. It was the only sticking point for me after realizing that pure [] = const [].
sequenceA [(+1)] = (:) <$> (+1) <*> const []
Using lambdas (so we can explicitly show and move things around when we start treating function application like a functor and an applicative):
sequenceA [(+1)] = \b c -> ( (:) b c ) <$> ( \a -> (+1) a ) <*> ( \a -> const [] a )
Both (<$>) and (<*>) are infixl 4. Which means we read and evaluate from left to right, i.e. we start with (<$>).
Where (<$>) :: Functor f => (a -> b) -> f a -> f b.
The effect of <$> is to pluck (+1) out of it's wrapper ((->) r), OR \a -> from our lambda code, and apply it to \b c -> ( (:) b c ) where it will take the place of b, then re-apply the wrapper (that's the \a that appears after the equals sign on the line below):
sequenceA [(+1)] = \a c -> ( (:) ((+1) a) c ) <*> ( \a -> const [] a )
Notice that (:) is still waiting for an argument c, and (+1) is still waiting for an a. Now, we get to the applicative part.
Remember that: (<*>) :: f (a -> b) -> f a -> f b. Our f here is the function application \a ->.
Both sides now have the same wrapper, namely \a ->. I'm keeping the a's in there to remind us where the a's will be applied later, so it does become a little pseudo-y here. The function application will be connected back up in just a jiffy. Both functions depend on the same a, precisely because they had the same function application wrapper i.e. an applicative. Without their \a -> wrappers (thanks to <*>), it goes like this:
( \c -> ( (:) ((+1) a) c ) ) (const [] a)
= ( (:) ((+1) a) (const [] a) ) -- Ignore those a's, they're placeholders.
Now, the very last thing that <*> does is to pop this result back into it's wrapper \a ->:
sequenceA [(+1)] = \a -> ( (:) ((+1) a) (const [] a) )
Sugaring this up a little bit gives:
sequenceA [(+1)] = \a -> (+1) a : const [] a
See! It makes perfect sense that an argument to sequenceA [(+1)] goes to both (+1) and const. Applying a 2, for instance, gives:
sequenceA [(+1)] 2 = (+1) 2 : const [] 2
Remember that const a b :: a -> b -> a, and therefore just ignores it's input:
sequenceA [(+1)] 2 = 3 : []
OR, more sweetly:
sequenceA [(+1)] 2 = [3]
I came across a Haskell function that tells whether a list is sorted, and I'm having trouble understanding how it works.
The code in question is
f = zipWith (<=) <*> tail
which I understand to be equivalent (in point-ful style) to
f' xs = zipWith (<=) xs (tail xs)
and as an example returns
f [4, 5, 1] == [True,False]
I take it that it has something to do with the list monad and sequential application, but would appreciate if someone could make the meaning more clear to me. What exactly is <*> doing here?
The <*> here isn't acting on the [a] applicative, it's acting in the (->) a applicative instance.
Essentially
instance Applicative ((->) a) where
pure = const -- same as monadic return
f <*> a = \x -> f x (a x)
So it acts like function application, but also wraps the application in a function and gives the argument to both sides.
So expanding your function
zipWith (<=) <*> tail
\x -> zipWith (<=) x (tail x)
\(x:xs) -> zipWith (<=) (x:xs) xs
In general it's correct to view <*> as just function application + some extra goodies. You can almost read it as whitespace!
<*> is actually from (->) a as Applicative Functor. It is a S-combinator which distributes the argument (list xs in your expansion) to two functions (zipWith (<=) and tail) in the manner that you specified in the expansion: (f <*> g) x = f x (g x).
To understand this, you need to check the type (<*>) is applied to. Since both of its arguments are a->b, we are talking about a->b as Applicative Functor - not List.
I am curious about where getZipList is defined in ghc.
Control.Applicative has this definition for ZipList.
newtype ZipList a = ZipList { getZipList :: [a] }
One way to use ZipLists is (from LYAH):
ghci> getZipList $ (+) <$> ZipList [1,2,3] <*> ZipList [100,100,100]
[101,102,103]
I am curious how getZipList knows what to return.
Perhaps I am missing something about the newtype keyword.
Thanks!
It's not just newtype, it works the same with data. What you seem to be unaware of is named field syntax,
newtype ZipList a = ZipList { getZipList :: [a] }
is almost the same as
newtype ZipList a = ZipList [a]
getZipList :: ZipList a -> [a]
getZipList (ZipList xs) = xs
but the named field syntax allows more convenient updating and pattern matching - in particular it's much more convenient for named fields in data types with multiple fields.
The named field (implicitly) defines the accessor function that extracts the contained data from the wrapped value.
The secret is not in the newtype definition but in the applicative instance it has for <*>
instance Applicative ZipList where
pure x = ZipList (repeat x)
ZipList fs <*> ZipList xs = ZipList [f x | (f,x) <- zip fs xs]
The default list is like this instead, and that is where the difference comes from
instance Applicative [] where
pure x = [x]
fs <*> xs = [f x | f <- fs, x <- xs]