A while ago, I asked a question about $, and got useful answers -- in fact, I thought I understood how to use it.
It seems I was wrong :(
This example shows up in a tutorial:
instance Monad [] where
xs >>= f = concat . map f $ xs
I can't for the life of me see why $ was used there; ghci isn't helping me either, as even tests I do there seem to show equivalence with the version that would simply omit the $. Can someone clarify this for me?
The $ is used here because it has lower precedence than normal function application.
Another way to write this code is like so:
instance Monad [] where
xs >>= f = (concat . map f) xs
The idea here is to first construct a function (concat . map f) and then apply it to its argument (xs). As shown, this can also be done by simply putting parenthesis around the first part.
Note that omitting the $ in the original definition is not possible, it will result in a type error. This is because the function composition operator (the .) has a lower precedence than normal function application effectively turning the expression into:
instance Monad [] where
xs >>= f = concat . (map f xs)
Which doesn't make sense, because the second argument to the function composition operator isn't a function at all. Although the following definition does make sense:
instance Monad [] where
xs >>= f = concat (map f xs)
Incidentally, this is also the definition I would prefer, because it seems to me to be a lot clearer.
I'd like to explain why IMHO this is not the used style there:
instance Monad [] where
xs >>= f = concat (map f xs)
concat . map f is an example of so-called pointfree-style writing; where pointfree means "without the point of application". Remember that in maths, in the expression y=f(x), we say that f is applied on the point x. In most cases, you can actually do a final step, replacing:
f x = something $ x
with
f = something
like f = concat . map f, and this is actually pointfree style.
Which is clearer is arguable, but the pointfree style gives a different point of view which is also useful, so sometimes is used even when not exactly needed.
EDIT: I have replaced pointless with pointfree and fixed some examples, after the comment by Alasdair, whom I should thank.
The reason $ is used here is doe to the type signature of (.):
(.) :: (b -> c) -> (a -> c) -> a -> c
Here we have
map f :: [a] -> [[b]]
and
concat :: [[b]] -> [b]
So we end up with
concat . map f :: [a] -> [b]
and the type of (.) could be written as
(.) :: ([[b]] -> [b]) -> ([a] -> [[b]]) -> [a] -> [b]
If we were to use concat . map f xs, we'd see that
map f xs :: [[b]]
And so cannot be used with (.). (the type would have to be (.) :: (a -> b) -> a -> b
Related
I'm trying to define the map function using foldr
I have found the two following solutions, however I'm not quite sure how they are working.
map' :: (a -> b) -> [a] -> [b]
map' f = foldr ((:) . f) []
map'' :: (a -> b) -> [a] -> [b]
map'' f = foldr (\x xs -> f x : xs) []
I'm quite new to Haskell and foldr, so I'm struggling to understand what ((:) . f) in the first solution and what (\x xs -> f x : xs) in the second solution do.
I also don't get how foldr is able handle the empty list case.
It would be much appreciated if I could get a simple step by step explanation of this, in layman's terms.
Both (\x xs -> f x : xs) and (:) . f mean the same thing. They're both functions that take two arguments, apply f to the first argument, and then cons that onto the second argument.
So what does foldr do when given an empty list? It simply returns the starting value, which in these examples is [].
Here is the implementation of foldr from Hackage:
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
I have a function that converts [a, b, c, d, . . . ] to [(a,b), (c, d), . . .]. Now this works and here is the code for that:
makeTuple :: [a] -> [(a,a)]
makeTuple [] = []
makeTuple [a] = []
makeTuple (x:y:xs) = (x,y): (makeTuple xs)
Now the next thing I have to do is this: Using the previous function, convert each tuple to a product of its two elements, using foldl and a lambda expression. And this is what I have:
productTuple [x] = foldl makeTuple [] [x]
Now I am not sure if this is exactly what is being asked of me. I'm not sure if I should make a separate function with the type declaration and whatnot. Maybe someone can tell me if that is the best way to approach this. Also this code does not work, and I don't know why,I need help with this part. (notice that it says to use a lambda, but I have no idea how to really properly use those, which is another part I need help with) I would really appreciate it, thanks.
The lambda function should respect this signature :
[a] -> (b,b) -> [a]
The accumulator has the type [a], the tuple has the type (b,b)
You can try a lambda like this \acc (a, b) -> acc++[a*b]
The final function could look like :
productTuple :: Num a => [a] -> [a]
productTuple xs = foldl (\acc (a, b) -> acc++[a*b]) [] (makeTuple xs)
You have some examples of foldl function here
I tried this code here
The exercise is asking you to preprocess the input lists with the makeTuple, and then fold over it.
productTuple :: [Int] -> [Int]
productTuple xs = foldl (some lambda) something (makeTuple xs)
It is not the most convenient way to do it, but I guess that the point of the exercise is to force you to use foldl just for the sake of it.
I'm attempting to make a function that generates the last item in a list. I want to use reverse and !!. This is what I have so far:
myLast :: [a] -> [a] -> Int -> a
myLast xs = (reverse xs) !! 1
I know the problem lies somewhere within the type, but I'm having trouble identifying how to fix it.
A function's type signature has nothing to do with what you use in the function, it only describes how other people can use this function you're defining. So by writing
myLast :: [a] -> [a] -> Int -> a
you're saying, users need to supply two lists and and integer. Just to get the last element of one of the lists?? That doesn't make sense.
You surely mean
myLast :: [a] -> a
You should generally write that down before even thinking about how you're going to implement that function.
With that signature, you can write various implementations:
myLast :: [a] -> a
myLast xs = head $ reverse xs
myLast' :: [a] -> a
myLast' [l] = l
myLast' (_:xs) = myLast' xs
myLast'' :: [a] -> a
myLast'' = fix $ \f (x:xs) -> maybe x id . teaspoon $ f xs
or whatever weird implementation you choose, it has nothing to do with the signature.
On an unrelated note: though last is actually a standard function from the prelude, it's a kind of function avoided in modern Haskell: last [] gives an error, because the is no a value to be found in the empty list! Errors are bad. Hence the “ideal” way to write it is actually
myLast :: [a] -> Maybe a
myLast [] = Nothing
myLast [x] = x
myLast (_:xs) = myLast xs
I would recommend not using !! at all, but to use head.
myLast xs = head (reverse xs)
Head returns the first element of the list it is given as argument.
If you insist on using !!, in Haskell arrays are indeed zero-based, which means that !! 0 gets the first element, !! 1 the second, etc.
As for the type: myLast takes an array of some type and returns one item of that same type. That is denoted as follows:
myLast :: [a] -> a
#leftaroundabout covered this way better in his answer.
Based on #leftaroundabout 's answer, here's an implementation that should do what you want:
safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:_) = Just x
myLast :: [a] -> Maybe a
myLast [] = Nothing
myLast xs = safeHead $ reverse xs
The Maybe type is constructed as follows (from Hackage):
data Maybe a = Nothing | Just a
deriving (Eq, Ord)
myLast [1, 2, 3, 4], for example, will return Just 4. If you want to use the value 4 you can use the function fromJust function from the Data.Maybe module (fromJust (Just 4) returns 4). fromJust is defined like this:
-- | The 'fromJust' function extracts the element out of a 'Just' and
-- throws an error if its argument is 'Nothing'.
--
-- ==== __Examples__
--
-- Basic usage:
--
-- >>> fromJust (Just 1)
-- 1
--
-- >>> 2 * (fromJust (Just 10))
-- 20
--
-- >>> 2 * (fromJust Nothing)
-- *** Exception: Maybe.fromJust: Nothing
--
fromJust :: Maybe a -> a
fromJust Nothing = error "Maybe.fromJust: Nothing" -- yuck
fromJust (Just x) = x
I've been learning about uncurrying and applying $ in functions in haskell but I'm still having issues converting an uncurried function to something less mysterious.
The function I'm given is
apple = map $ uncurry $ flip ($)
and I realize that this takes a list of tuples and applies to corresponding function in the tuple to the variable inside. So I'm trying to rewrite it as
apple ls = foldr function _ ls
where function (a,b) c = (uncurry b) (a,c)
I get the error for _ as a parse error and I have no idea which starting point to use. I need to make this polymorphic and I'm realizing that this most likely will not be the way to make it less mysterious. Any ideas? They'd be greatly appreciated
Apple has the type
apple :: [(a, a->b)] -> [b]
We could rewrite it as
apple ls = map (\(a, f) -> f a) ls
So writing this with foldr is very doable,
apple ls = foldr (\(a, f) rest -> f a : rest) [] ls
Or, we can rewrite this to pointfree
apple = foldr ( (:) . (uncurry . flip $ ($)) ) []
The reason for the parse error is that _ is the special syntax for "variables I don't care about". This let's you write things like
foo _ _ _ _ a = a
And not get an error about repeated variables. Basically we just filled in _ with the starting empty list and fixed function so that it appends to c rather than trying to apply it to a.
If I wanted to write this in the clearest way possible, then the original
apple = map . uncurry . flip $ ($)
Is quite nice.
The key for understanding is removing complexity.
Thus I would suggest you deal with a single tuple first. Write the following function:
tapp :: (a, a ->b) -> b
in terms of ($) and flip and uncurry.
(To make it even easier, you could first do it for a tuple (a -> b, a) first).
Next, make clear to yourself how map works: If you have a function f :: (a -> b), then map f will be a function [a] -> [b]. Hence map tapp does what you want.
You can now replace tapp in map (tapp) by it's definition (this are the benefits of referential transparency).
And this should take you back to your original expression. More or less so, because, for example:
f $ g h
can be written
f (g h)
or
(f . g) h
Instead of fmap, which applies a function to a value-in-a-functor:
fmap :: Functor f => (a -> b) -> f a -> f b
I needed a function where the functor has a function and the value is plain:
thing :: Functor f => f (a -> b) -> a -> f b
but I can't find one.
What is this pattern called, where I apply a function-in-a-functor (or in an applicative, or in a monad) to a plain value?
I've implemented it already, I just don't quite understand what I did and why there wasn't already such a function in the standard libraries.
You don't need Applicative for this; Functor will do just fine:
apply f x = fmap ($ x) f
-- or, expanded:
apply f x = fmap (\f' -> f' x) f
Interestingly, apply is actually a generalisation of flip; lambdabot replaces flip with this definition as one of its generalisations of standard Haskell, so that's a possible name, although a confusing one.
By the way, it's often worth trying Hayoo (which searches the entirety of Hackage, unlike Hoogle) to see what names a function is often given, and whether it's in any generic package. Searching for f (a -> b) -> a -> f b, it finds flip (in Data.Functor.Syntax, from the functors package) and ($#) (from the synthesizer package) as possible names. Still, I'd probably just use fmap ($ arg) f at the use site.
As Niklas says, this is application in some applicative functor to a lifted value.
\f a -> f <*> pure a
:: Applicative f => f (a -> b) -> a -> f b
or more generally (?), using Category (.)
\f a -> f . pure a
:: (Applicative (cat a), Category cat) => cat b c -> b -> cat a c