I want to write an expression which will give a list that is equal to the list comprehension [x|x<-[1..100], x`mod`7==0], but I'm asked by my teacher to use $ in this program.
So, how could I use $ in here?
PS: I'm new to Haskell, so would prefer easy expressions, please.
($) is in an infix operator with a type signature
($) :: (a -> b) -> a -> b
which means it takes two parameters, first a function (a -> b) (on the left) which accepts a single parameter, a value of type designated by the type variable a. The second parameter of ($) (on the right) is a single value again designated by the type variable a. Then the ($) operator simply applies it's second parameter to the first parameter. So for an example (+2) $ 3 would give us 5.
So if you insist on doing list comprehensions you may do as follows in point-free style;
Prelude> [x|x<-[1..100], (== 0) . mod x $ 7]
[7,14,21,28,35,42,49,56,63,70,77,84,91,98]
or in a more straightforward fashion
Prelude> filter ((==0) . (`mod` 7)) $ take 100 [1..]
[7,14,21,28,35,42,49,56,63,70,77,84,91,98]
$ just means "take whatever is on the right, and pass it as argument to the left".
So for example :
map (`mod`7) (take 100 [1..])
map (`mod`7) $ take 100 [1..]
Those two lines are the same, the $ just means you can avoid the parenthesis around the second call.
The take is useless but I didn't have a better idea for a simple example :)
Related
is it possible to use map with 2 operators in it like map ((*2)+3) [1,2,3,4]? If is yes how? i want to make a function that apply (x*2)+3 on a list.
You map a single function. But that function can do whatever you want. Your example can be given as an anonymous function for example:
map (\n -> n * 2 + 3) [1,2,3,4]
But you can also use function composition, which is likely more readable for a case like this where your function is a case of "do one thing, then the other":
map ((+3) . (*2)) [1,2,3,4]
This in turn is equal (by the so-called "functor laws") to
map (+3) . map (*2) $ [1,2,3,4]
Which I personally find a little more readable.
I think it is easy to first introduce a lambda expression here:
map (\x -> (x*2)+3) [1,2,3,4]
This will do exactly what you want. You can perform "function composition" with the (.) :: (b -> c) -> (a -> b) -> a -> c function, and thus write this as:
map ((+3) . (*2)) [1,2,3,4]
Here you thus can see it as a "chain" of functions, where we pass the input to the rightmost function (here (*2)), and then the result is passed to the leftmost function (here (+3)).
I just want to know how do we know which functions need brackets () and which ones do not? For example
replicate 100 (product (map (*3) (zipWith max [1,2,3,4,5] [4,5,6,7,8])))
works fine. But
replicate 100 (product (map (*3) (zipWith (max [1,2,3,4,5] [4,5,6,7,8]))))
does not work. It is because I put a set of brackets for zipWith. In this small example, zipWith and max do not have brackets, but replicate, product and map do. In general is there a way to know/figure out which functions need brackets and which ones dont.
Function application is left associative. So, when you write an expression like:
f g h x
it means:
((f g) h) x
And also the type of zipWith provides a clue:
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
it says that zipWith has 3 parameters: a function and two lists.
When you write:
zipWith (max [1,2,3,4,5] [4,5,6,7,8])
The interpreter will understand that
max [1,2,3,4,5] [4,5,6,7,8]
will be the first parameter to zipWith, which is type incorrect. Note that zipWith expects a function of two arguments as its first argument and, as pointed out by #Cubic, max [1,2,3,4,5] [4,5,6,7,8] will return the maximum
between these two lists according the usual lexicographic order, which will be of type [a], for some type a which is instance of Ord and Num. Said that, the error become evident since you are trying to pass a value of type
(Num a, Ord a) => [a]
where a value of type
(a -> b -> c)
is expected.
Rodrigo gave the right answer. I'll just add that it is a misconception to think that some functions need parentheses, while others don't.
This is just like in school math:
3 * (4+5)
It is simply not the case that + expressions need parentheses and * expressions don't need them in general.
In Haskell, you can always get away without parentheses at all. Whenever you need to enclose an expression in parentheses, the alternative is to introduce a local name and bind it to that expression, then use the name instead of the expression.
In your example:
replicate 100 (product (map (*3) (zipWith max [1,2,3,4,5] [4,5,6,7,8])))
let list1 = product list2
list2 = map thrice list3
thrice x = x*3
list3 = zipWith max [1,2,3,4,5] [4,5,6,7,8]
in replicate 100 list1
In fact, I often write functions top down thus:
foo x y z = result
where
result = ...
...
However, as it was said before, expressions that consist of function applications can also often be written without parentheses by making use of (.) and ($) and in such cases, the top down approach from above may be overly verbose and the following would be much clearer (because there is no noise through newly introduced names):
replicate 100
. product
. map (*3)
$ zipWith max [1..5] [4..8]
While trying to write a function for transposing a list of lists, I saw something very curious. I tried:
> let abc xs | null (head xs) = [] | otherwise = map head xs : abc $ map tail xs
and got an error. Then I tried:
> let abc xs | null (head xs) = [] | otherwise = map head xs : abc ( map tail xs )
> abc [[1,2,3], [4,5,6], [7,8,9]]
[[1,4,7],[2,5,8],[3,6,9]]
I was led to believe that the $ operator can be used instead of the brackets, and that that's more Haskellish. Why am I getting an error?
An operator is a function that can be applied in a infix position. So $ is a function.
In Haskell, you can define your own functions that can be used in infix position - between the arguments. Then you can also define function application precedence and associativity using infix, infixr, infixl - that is, the clues telling the compiler whether to treat a $ b $ c as (a $ b) $ c, or a $ (b $ c).
The precedence of $ is such that your first expression is interpreted like (map head xs : abc) $ ...
For example, to declare $ as infix, place its name in ():
($) :: (a->b) -> a -> b
f $ x = f x
or composition:
(.) :: (b->c)->(a->b)->a->c
(f . g) x = f $ g x
Arithemtic "operators" are also defined as infix functions in class Num.
Additionally, you can use other functions as infix, by quoting them in backticks `` at the application site. Sometimes it makes the expression look prettier:
f `map` xs == map f xs
(not that in this particular case it makes it look pretty, just to show a simple example)
Adding to Sassa's correct answer, let's dissect the code snippet you provided a bit further:
map head xs : abc $ map tail xs
Two operators are used here: (:) and ($). As noted above, these are interpreted as infix by default because their names consist only of symbols.
Each operator has a precedence which decides how 'tightly' it binds or, perhaps more usefully, which operator is applied first. Your code could be interpreted either as
((map head xs) : abc) $ (map tail xs)
where (:) binds more tightly (is applied before) ($) or as
(map head xs) : (abc $ (map tail xs))
where ($) binds more tightly. Note that I have put parentheses around function application (for example map applied to tail and xs) as well. Function application binds more tightly than any operator and is thus always applied first.
To decide which of the two ways to interpret the code is correct, the compiler needs to get information about which operator should bind more tightly. This is done using a fixity declaration like
infix 8
or in general
infix i
where i is between 0 and 9. Higher values of i mean that an operator binds more tightly. (infixr and infixl may be used to additionally define associativity as explained in Sassa's answer, but this doesn't affect your specific problem.)
As it turns out, the fixity declaration for the ($) operator is
infixr 0 $
as seen in the Prelude documentation. (:) is a bit more 'magic' because it is hard-coded into the Haskell syntax, but the Haskell Report specifies that it has precedence 5.
Now we finally have enough information to conclude that the first interpretation of your code is indeed correct: the precedence of (:), 5, is higher than the precedence of ($), 0. As a general rule of thumb, ($) often doesn't interact well with other operators.
By the way, if an expression contains two different operators which have the same precedence (such as (==) and (/=)), the order in which they should be applied is unclear, so you have to use parentheses to specify it explicitly.
I want to filter everything that is not divisible by 3 from a list in Haskell, this is technically what I want to do
filter (`mod` 3) [1..100]
The problem is, mod x 3 won't return a boolean value. Is there a way to do this in one line? or am I forced to write another function which returns a boolean value? I've read about curried functions, but I'm not sure if its possible to do this because if I used (==) a b and a is a function, it just wouldn't work out.
That is what function composition is for:
filter ((== 0) . (`mod` 3)) [1..100]
As ever, contemplate the types of the involved functions until everything feels natural.
you can use dot notation
filter ((== 0) . (`mod` 3)) [1..100]
this generates
[3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99]
The type signature of dot is as follows:
(.) :: (b -> c) -> (a -> b) -> a -> c
If you want to define it in one line and don't want to write another function (which is going to be used in just one place anyway), the easiest way is to define lambda function:
filter (\x -> x `mod` 3 == 0) [1..100]
Point-free style suggested in other answers can sometimes lead to "hard to read" expressions when the auxiliary function is more complex then this. Especially for a beginner.
You can also use a list comprehension:
[x | x <- [1..100], (x `mod` 3) == 0]
An alternative version, using streams:
takeWhile (<=100) $ map (*3) [1..]
My aim is to list all elements of the array a whose values are greater than their index positions. I wrote a Haskell code like this.
[a|i<-[0..2],a<-[1..3],a!!i>i]
When tested on ghci prelude prompt, I get the following error message which I am unable to understand.
No instance for (Num [a]) arising from the literal 3 at <interactive>:1:20 Possible fix: add an instance declaration for (Num [a])
Given the expression a!!i, Haskell will infer that a is a list (i.e. a::[a]). Given the expression a<-[1..3], Haskell will infer that a will have type Num a => a (because you are drawing a from a list of Num a => a values). Trying to unify these types, Haskell concludes that a must actually be of type Num a => [a].
The bottom line is that it doesn't make sense to treat a as a list in one context and as an element from a list of numbers in another context.
EDIT
I'm thinking you could do what you want with something like this:
f xs = map fst . filter (uncurry (>)) $ (xs `zip` [0..])
The expression xs `zip` [0..] creates a list of pairs, where the first value in each pair is drawn from xs and the second value from [0..] (an infinite list starting from 0). This serves to associate an index to each value in xs. The expression uncurry (>) converts the < operator into a function that works on pairs. So the expression filter (uncurry (>)) filters a list of pairs to only those elements where the first value is greater than the second. Finally, map fst applies the fst function to each pair of values and returns the result as a list (the fst function returns the first value of a pair).
EDIT 2
Writing pointless code is fun, and so I give you:
f = map snd . filter (uncurry (<)) . zip [0..]
import Data.Maybe
import Control.Monad
f = catMaybes . zipWith (mfilter.(<)) [0..] . map Just
Disclaimer: The given code was not proof read and may have been made outside of sobriety. The author has little recollection of what it is about.