I was playing around with a simple function for someone else's Stack Overflow question, and wrote the expression:
f a x ++ f a y
Obviously this is the best way to write that expression in real life, given I have all those variables in scope anyway, but I saw the duplication of f a, and thought "Hey, maybe you can remove that with the Applicative instance for functions". I wound up with:
liftA2 (++) (flip f x) (flip f y) a
which is just awful. Is there some nicer way to remove this duplication?Obviously I could also remove the duplication by binding f a to something in a where clause, but this was intended as an exercise in using built-in functions.
You could do
((++) `on` f a) x y
That doesn't use Applicative, though (sorry).
[...] maybe you can remove that with the Applicative instance for functions.
Do you have to use the Applicative instance of ((->) t)? If you just want to get rid of the duplicated f a, why not use the list monad, instead?
[x, y] >>= f a
or, equivalently,
f a =<< [x, y]
Example:
λ> let f :: Int -> Int -> [Int]; f a x = [a .. x]
λ> f 1 2 ++ f 1 3
[1,2,1,2,3]
λ> [2, 3] >>= f 1
[1,2,1,2,3]
λ> f 1 =<< [2, 3]
[1,2,1,2,3]
Bikeshedding is fun! Another option would be to use the Monoid instance for functions:
(($x) <> ($y)) (f a)
Since the question hinted at a solution using Applicative (although other answers are more elegant)...
((++) <$> ($ x) <*> ($ y)) (f a)
Related
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 am puzzling over how to best express some operations in the most idiomatic and clear way. Currently (there will be more to come) I'm puzzling over <*> (I'm not even sure what to call that).
For example, if I have, say
f = (^2)
g = (+10)
as representative functions (in practice they are more complex, but the key thing here is that they are different and distinct), then
concatMap ($ [1,2,3,4,10]) [(f <$>), (g <$>) . tail . reverse]
and
concat $ [(f <$>), (g <$>) . tail . reverse] <*> [[1,2,3,4,10]]
accomplish the same thing.
Is one of these more idiomatic Haskell, does one imply something an experienced reader of Haskell that the other does not. Perhaps there are additional (better) ways to express exactly the same thing. Are there conceptual differences between the two approaches that a novice Haskeller like myself may be missing?
Both your functions (f <$>) and (g <$>).tail.reverse return a monoid type (list in this case) so you can use mconcat to convert them into a single function. Then you can apply this function directly to the input list instead of wrapping it in another list and using concatMap:
mconcat [(f <$>), (g <$>).tail.reverse] $ [1,2,3,4,10]
To expand on this, a function a -> b is an instance of Monoid if b is a monoid. The implementation of mappend for such functions is:
mappend f g x = f x `mappend` g x
or equivalently
mappend f g = \x -> (f x) `mappend` (g x)
so given two functions f and g which return a monoid type b, fmappendg returns a function which applies its argument to f and g and combines the results using the Monoid instance of b.
mconcat has type Monoid a => [a] -> a and combines all the elements of the input list using mappend.
Lists are monoids where mappend == (++) so
mconcat [(f <$>), (g <$>).tail.reverse]
returns a function like
\x -> (fmap f x) ++ (((fmap g) . tail . reverse) x)
Personally for your example I would write
f = (^2)
g = (+10)
let xs = [1,2,3,4,10]
in (map f xs) ++ (map g . tail $ reverse xs)
In a very Applicative "mood", I would replace the part after in by
((++) <$> map f <*> map g . tail . reverse) xs
which I actually don't think is more readable in this case. If you don't directly understand what it means, spend some time on understanding the Applicative instance of ((->) a) (Reader).
I think the choice really depends on what you're trying to do, i.e. what your output is supposed to mean. In your example the task is very abstract (basically just showcasing what Applicative can do), so it's not directly obvious which version to use.
The Applicative instance of [] intuitively relates to combinations, so I would use it in a situation like this:
-- I want all pair combinations of 1 to 5
(,) <$> [1..5] <*> [1..5]
If you would have many functions, and you would want to try all combinations of these functions with a number of arguments, I would indeed use the [] instance of Applicative. But if what you're after is a concatenation of different transformations I would write it as such (which I did, above).
Just my 2 cents as a medium-experience Haskeller.
I sometimes struggle with the similar problem. You have single element but multiple functions.
Usually we have multiple elements, and single function: so we do:
map f xs
But it's not the problem in Haskell. The dual is as easy:
map ($ x) fs
The fact, that your x is actually a list, and you want to concat after the map, so you do
concatMap ($ xs) fs
I cannot really understand what happens in the second equation directly, even I can reason it does the same as first one using applicative laws.
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 use this a fair bit:
a' = [ (f x, f y) | (x, y) <- a ]
Is there a better way to do that?
You can use the (***) operator from Control.Arrow
> map (f *** f) a
or define your own helper function
> let both f (x, y) = (f x, f y)
> map (both f) a
Alternative solution:
import Data.Bifunctor
bimap f f pair
Bifunctor.bimap is basically the same as Arrow.(***), but works for other bifunctors (like Either a b), too.
Digression:
The reason why there is nothing predefined for your case is that you can't write instances of Functor, Applicative etc for (,) having the same element type twice. With an own "vector-like" type you wouldn't have this problem:
data Pair a = Pair a a deriving Show
instance Functor Pair where
fmap f (Pair x y) = Pair (f x) (f y)
Now you can write things like map (fmap (+1)) [Pair 12 14, Pair 17 18]. Or if you want to use different operations on your Pair, you can go one step further:
instance Applicative Pair where
pure x = Pair x x
(Pair f g) <*> (Pair x y) = Pair (f x) (g y)
If you work a lot with same-element-type pairs, it could be useful to switch from (,) to such a type.
If you use lens, you can use over both f, or both %~ f. This has the advantage of being more composable -- for example, if you have a pair of lists, you can use something like both.mapped +~ toUpper (:: ([Char],[Char]) -> ([Char],[Char])).
From time to time I stumble over the problem that I want to express "please use the last argument twice", e.g. in order to write pointfree style or to avoid a lambda. E.g.
sqr x = x * x
could be written as
sqr = doubleArgs (*) where
doubleArgs f x = f x x
Or consider this slightly more complicated function (taken from this question):
ins x xs = zipWith (\ a b -> a ++ (x:b)) (inits xs) (tails xs)
I could write this code pointfree if there were a function like this:
ins x = dup (zipWith (\ a b -> a ++ (x:b))) inits tails where
dup f f1 f2 x = f (f1 x) (f2 x)
But as I can't find something like doubleArgs or dup in Hoogle, so I guess that I might miss a trick or idiom here.
From Control.Monad:
join :: (Monad m) -> m (m a) -> m a
join m = m >>= id
instance Monad ((->) r) where
return = const
m >>= f = \x -> f (m x) x
Expanding:
join :: (a -> a -> b) -> (a -> b)
join f = f >>= id
= \x -> id (f x) x
= \x -> f x x
So, yeah, Control.Monad.join.
Oh, and for your pointfree example, have you tried using applicative notation (from Control.Applicative):
ins x = zipWith (\a b -> a ++ (x:b)) <$> inits <*> tails
(I also don't know why people are so fond of a ++ (x:b) instead of a ++ [x] ++ b... it's not faster -- the inliner will take care of it -- and the latter is so much more symmetrical! Oh well)
What you call 'doubleArgs' is more often called dup - it is the W combinator (called warbler in To Mock a Mockingbird) - "the elementary duplicator".
What you call 'dup' is actually the 'starling-prime' combinator.
Haskell has a fairly small "combinator basis" see Data.Function, plus some Applicative and Monadic operations add more "standard" combinators by virtue of the function instances for Applicative and Monad (<*> from Applicative is the S - starling combinator for the functional instance, liftA2 & liftM2 are starling-prime). There doesn't seem to be much enthusiasm in the community for expanding Data.Function, so whilst combinators are good fun, pragmatically I've come to prefer long-hand in situations where a combinator is not directly available.
Here is another solution for the second part of my question: Arrows!
import Control.Arrow
ins x = inits &&& tails >>> second (map (x:)) >>> uncurry (zipWith (++))
The &&& ("fanout") distributes an argument to two functions and returns the pair of the results. >>> ("and then") reverses the function application order, which allows to have a chain of operations from left to right. second works only on the second part of a pair. Of course you need an uncurry at the end to feed the pair in a function expecting two arguments.