How come I can write the first version but not the second? - haskell

We are trying to learn Haskell (for about the 5th time!) and still struggling with some basic issues.
So how come I can write
main = print (map (* 2) [1..5])
but I can't write
myfunc x =
map ( (+ x) [1..5])
main = print (myfunc 2)
Any guidance would be appreciated --- we have the usual books but they're not really helping.

You got the parentheses wrong. You want:
myfunc x = map (+x) [1..5]

In hopes of clearing up whatever misunderstanding prompted this: In Haskell, function application is left-associative, higher "precedence" than any infix operator, and does not require any parentheses. Parentheses are used only for grouping subexpressions: (f x) y is the same as just f x y, while f (g x) needs the parentheses.

Related

What is the best way to do "replace-if"?

I'm thinking of a function that can replace the value x with z when x is y, and do nothing otherwise, that is:
\x -> if x == y then z else x
It's only used once in my program and it's in the middle of a function chain so I don't want to define it as a named function and I think the lambda expression looks unnecessarily verbose. Instead, I'm trying to compose it from other functions. However, so far I have only come up with this cryptic (and cring-y) one:
(ap . flip . bool id $ const z) (== y)
Are there better point-free forms for such a simple function?
I don't know of anything very readable. Shortest I can get is
bool z <*> (/= y)
Further silly ways:
execState (gets (==y) >>= flip when (put z))
fromMaybe <*> flip lookup [(y, z)]
I don't approve of this very much, but a quick Hayoo search led me to the (?|) operator in the data-easy package. This package is full of such functions (with a bunch of disclaimers about "non-idiomatic haskell"). Looks like you could have
\x -> if x == y then z else x -- the cluttered Haskell form
\x -> x ?| (/= y) $ z -- the "Pythonic" form
(?| (/= y)) z -- Haskell-sections-galore of the "Pythonic" form
Jokes aside, there is also the much more reasonable fromBoolC that you will probably like:
fromBoolC z (/= y)
From lens:
import Control.Lens
f = (^. non z) . (non y # ) -- for some z and y
The if then else version is definitely better though.
You can use the Python trick of replacing a case statement with a lookup.
import Data.Map
\x -> findWithDefault x x (singleton y z)
which according to pointfree.io can be reduced to
flip (join findWithDefault) (singleton y z)
It's not exactly clear, but at the same time it separates the functional parts from the arguments. flip (join findWithDefault) does what you want, and singleton y z is a DSL-like way of specifying the exception. Stick a idExcept = flip (join findWithDefault) and exception = singleton earlier in your code, and your chain is almost readable.
my . awesome . (idExcept (exception y z)) . function . chain $ val

Partial application of functions and currying, how to make a better code instead of a lot of maps?

I am a beginner at Haskell and I am trying to grasp it.
I am having the following problem:
I have a function that gets 5 parameters, lets say
f x y w z a = x - y - w - z - a
And I would like to apply it while only changing the variable x from 1 to 10 whereas y, w, z and a will always be the same. The implementation I achieved was the following but I think there must be a better way.
Let's say I would like to use:
x from 1 to 10
y = 1
w = 2
z = 3
a = 4
Accordingly to this I managed to apply the function as following:
map ($ 4) $ map ($ 3) $ map ($ 2) $ map ($ 1) (map f [1..10])
I think there must be a better way to apply a lot of missing parameters to partially applied functions without having to use too many maps.
All the suggestions so far are good. Here's another, which might seem a bit weird at first, but turns out to be quite handy in lots of other situations.
Some type-forming operators, like [], which is the operator which maps a type of elements, e.g. Int to the type of lists of those elements, [Int], have the property of being Applicative. For lists, that means there is some way, denoted by the operator, <*>, pronounced "apply", to turn lists of functions and lists of arguments into lists of results.
(<*>) :: [s -> t] -> [s] -> [t] -- one instance of the general type of <*>
rather than your ordinary application, given by a blank space, or a $
($) :: (s -> t) -> s -> t
The upshot is that we can do ordinary functional programming with lists of things instead of things: we sometimes call it "programming in the list idiom". The only other ingredient is that, to cope with the situation when some of our components are individual things, we need an extra gadget
pure :: x -> [x] -- again, one instance of the general scheme
which wraps a thing up as a list, to be compatible with <*>. That is pure moves an ordinary value into the applicative idiom.
For lists, pure just makes a singleton list and <*> produces the result of every pairwise application of one of the functions to one of the arguments. In particular
pure f <*> [1..10] :: [Int -> Int -> Int -> Int -> Int]
is a list of functions (just like map f [1..10]) which can be used with <*> again. The rest of your arguments for f are not listy, so you need to pure them.
pure f <*> [1..10] <*> pure 1 <*> pure 2 <*> pure 3 <*> pure 4
For lists, this gives
[f] <*> [1..10] <*> [1] <*> [2] <*> [3] <*> [4]
i.e. the list of ways to make an application from the f, one of the [1..10], the 1, the 2, the 3 and the 4.
The opening pure f <*> s is so common, it's abbreviated f <$> s, so
f <$> [1..10] <*> [1] <*> [2] <*> [3] <*> [4]
is what would typically be written. If you can filter out the <$>, pure and <*> noise, it kind of looks like the application you had in mind. The extra punctuation is only necessary because Haskell can't tell the difference between a listy computation of a bunch of functions or arguments and a non-listy computation of what's intended as a single value but happens to be a list. At least, however, the components are in the order you started with, so you see more easily what's going on.
Esoterica. (1) in my (not very) private dialect of Haskell, the above would be
(|f [1..10] (|1|) (|2|) (|3|) (|4|)|)
where each idiom bracket, (|f a1 a2 ... an|) represents the application of a pure function to zero or more arguments which live in the idiom. It's just a way to write
pure f <*> a1 <*> a2 ... <*> an
Idris has idiom brackets, but Haskell hasn't added them. Yet.
(2) In languages with algebraic effects, the idiom of nondeterministic computation is not the same thing (to the typechecker) as the data type of lists, although you can easily convert between the two. The program becomes
f (range 1 10) 2 3 4
where range nondeterministically chooses a value between the given lower and upper bounds. So, nondetermism is treated as a local side-effect, not a data structure, enabling operations for failure and choice. You can wrap nondeterministic computations in a handler which give meanings to those operations, and one such handler might generate the list of all solutions. That's to say, the extra notation to explain what's going on is pushed to the boundary, rather than peppered through the entire interior, like those <*> and pure.
Managing the boundaries of things rather than their interiors is one of the few good ideas our species has managed to have. But at least we can have it over and over again. It's why we farm instead of hunting. It's why we prefer static type checking to dynamic tag checking. And so on...
Others have shown ways you can do it, but I think it's useful to show how to transform your version into something a little nicer. You wrote
map ($ 4) $ map ($ 3) $ map ($ 2) $ map ($ 1) (map f [1..10])
map obeys two fundamental laws:
map id = id. That is, if you map the identity function over any list, you'll get back the same list.
For any f and g, map f . map g = map (f . g). That is, mapping over a list with one function and then another one is the same as mapping over it with the composition of those two functions.
The second map law is the one we want to apply here.
map ($ 4) $ map ($ 3) $ map ($ 2) $ map ($ 1) (map f [1..10])
=
map ($ 4) . map ($ 3) . map ($ 2) . map ($ 1) . map f $ [1..10]
=
map (($ 4) . ($ 3) . ($ 2) . ($ 1) . f) [1..10]
What does ($ a) . ($ b) do? \x -> ($ a) $ ($ b) x = \x -> ($ a) $ x b = \x -> x b a. What about ($ a) . ($ b) . ($ c)? That's (\x -> x b a) . ($ c) = \y -> (\x -> x b a) $ ($ c) y = \y -> y c b a. The pattern now should be clear: ($ a) . ($ b) ... ($ y) = \z -> z y x ... c b a. So ultimately, we get
map ((\z -> z 1 2 3 4) . f) [1..10]
=
map (\w -> (\z -> z 1 2 3 4) (f w)) [1..10]
=
map (\w -> f w 1 2 3 4) [1..10]
=
map (\x -> ($ 4) $ ($ 3) $ ($ 2) $ ($ 1) $ f x) [1..10]
In addition to what the other answers say, it might be a good idea to reorder the parameters of your function, especially x is usually the parameter that you vary over like that:
f y w z a x = x - y - w - z - a
If you make it so that the x parameter comes last, you can just write
map (f 1 2 3 4) [1..10]
This won't work in all circumstances of course, but it is good to see what parameters are more likely to vary over a series of calls and put them towards the end of the argument list and parameters that tend to stay the same towards the start. When you do this, currying and partial application will usually help you out more than they would otherwise.
Assuming you don't mind variables you simply define a new function that takes x and calls f. If you don't have a function definition there (you can generally use let or where) you can use a lambda instead.
f' x = f x 1 2 3 4
Or with a lambda
\x -> f x 1 2 3 4
Currying won't do you any good here, because the argument you want to vary (enumerate) isn't the last one. Instead, try something like this.
map (\x -> f x 1 2 3 4) [1..10]
The general solution in this situation is a lambda:
\x -> f x 1 2 3 4
however, if you're seeing yourself doing this very often, with the same argument, it would make sense to move that argument to be the last argument instead:
\x -> f 1 2 3 4 x
in which case currying applies perfectly well and you can just replace the above expression with
f 1 2 3 4
so in turn you could write:
map (f 1 2 3 4) [1..10]

Haskell, passing a function to filter in one line?

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..]

Avoid pattern matching in recursion

Consider this code which I used to solve Euler Problem 58:
diagNums = go skips 2
where go (s:skips) x = let x' = x+s
in x':go skips (x'+1)
squareDiagDeltas = go diagNums
where go xs = let (h,r) = splitAt 4 xs
in h:go r
I don't like the pattern matching in the second function. It looks more complicated than necessary! This is something that arises pretty frequently for me. Here, splitAt returns a tuple, so I have to destructure it first before I can recurse. The same pattern arises perhaps even more annoyingly when my recursion itself returns a tuple I want to modify. Consider:
f n = go [1..n]
where go [] = (0,0)
go (x:xs) = let (y,z) = go xs
in (y+x, z-x)
compared to the nice and simple recursion:
f n = go [1..n]
where go [] = 0
go (x:xs) = x+go xs
Of course the functions here are pure nonsense and could be written in a wholly different and better way. But my point is that the need for pattern matching arises every time I need to thread more than one value back through the recursion.
Are there any ways to avoid this, perhaps by using Applicative or anything similar? Or would you consider this style idiomatic?
First of all, that style is actually rather idiomatic. Since you're doing two things to two different values, there is some irreducible complexity; the actual pattern match does not introduce much on its own. Besides, I personally find the explicit style very readable most of the time.
However, there is an alternative. Control.Arrow has a bunch of functions for working with tuples. Since the function arrow -> is an Arrow as well, all these work for normal functions.
So you could rewrite your second example using (***) to combine two functions to work over tuples. This operator has the following type:
(***) :: a b c -> a b' c' -> a (b, b') (c, c')
If we replace a with ->, we get:
(***) :: (b -> c) -> (b' -> c') -> ((b, b') -> (c, c'))
So you could combine (+ x) and (- x) into a single function with (+ x) *** (- x). This would be equivalent to:
\ (a, b) -> (a + x, b - x)
Then you could use it in your recursion. Unfortunately, the - operator is stupid and doesn't work in sections, so you would have to write it with a lambda:
(+ x) *** (\ a -> a - x) $ go xs
You can obviously imagine using any other operator, all of which aren't quite as stupid :).
Honestly, I think this version is less readable than the original. However, in other cases, the *** version can be more readable, so it's useful to know about it. In particular, if you were passing (+ x) *** (- x) into a higher-order function instead of applying it immediately, I think the *** version would be better than an explicit lambda.
I agree with Tikhon Jelvis that there is nothing wrong with your version. Like he said, using combinators from Control.Arrow can be useful with higher order functions. You can write f using a fold:
f n = foldr (\x -> (+ x) *** subtract x) (0,0) [1..n]
And if you really want to get rid of the let in squareDiagDeltas (I'm not sure I would), you can use second, because you are only modifying the second element of the tuple:
squareDiagDeltas = go diagNums
where go = uncurry (:) . second go . splitAt 4
I agree with hammar, unfoldr is the way to go here.
You can also get rid of the pattern matching in diagNums:
diagNums = go skips 2
where go (s:skips) x = let x' = x+s
in x':go skips (x'+1)
The recursion makes it a little difficult to tell what's going on here, so let's
examine it in depth.
Suppose skips = s0 : s1 : s2 : s3 : ..., then we have:
diagNums = go skips 2
= go (s0 : s1 : s2 : s3 : ...) 2
= s0+2 : go (s1 : s2 : s3 : ... ) (s0+3)
= s0+2 : s0+s1+3 : go (s2 : s3 : ... ) (s0+s1+4)
= s0+2 : s0+s1+3 : s0+s1+s2+4 : go (s3 : ... ) (s0+s1+s2+5)
= s0+2 : s0+s1+3 : s0+s1+s2+4 : s0+s1+s2+s3+5 : go (...) (s0+s1+s2+s3+6)
This makes it much clearer what's going on, we've got the sum of two sequences, which is easy to compute using zipWith (+):
diagNums = zipWith (+) [2,3,4,5,...] [s0, s0+s1, s0+s1+s2, s0+s1+s2+s3,...]
So now we just need to find a better way to compute the partial sums of skips, which is a great use for scanl1:
scanl1 (+) skips = s0 : s0+s1 : s0+s1+s2 : s0+s1+s2+s3 : ...
Leaving a (IMO) much easier to understand definition for diagNums:
diagNums = zipWith (+) [2..] $ scanl1 (+) skips

Partial Application with Infix Functions

While I understand a little about currying in the mathematical sense, partially
applying an infix function was a new concept which I discovered after diving
into the book Learn You a Haskell for Great Good.
Given this function:
applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)
The author uses it in a interesting way:
ghci> applyTwice (++ [0]) [1]
[1,0,0]
ghci> applyTwice ([0] ++) [1]
[0,0,1]
Here I can see clearly that the resulting function had different parameters
passed, which would not happen by normal means considering it is a curried
function (would it?). So, is there any special treatment on infix sectioning by
Haskell? Is it generic to all infix functions?
As a side note, this is my first week with Haskell and functional programming,
and I'm still reading the book.
Yes, you can partially apply an infix operator by specifying either its left or right operand, just leaving the other one blank (exactly in the two examples you wrote).
So, ([0] ++) is the same as (++) [0] or \x -> [0] ++ x (remember you can turn an infix operator into a standard function by means of parenthesis), while (++ [0]) equals to \x -> x ++ [0].
It is useful to know also the usage of backticks, ( `` ), that enable you to turn any standard function with two arguments in an infix operator:
Prelude> elem 2 [1,2,3]
True
Prelude> 2 `elem` [1,2,3] -- this is the same as before
True
Prelude> let f = (`elem` [1,2,3]) -- partial application, second operand
Prelude> f 1
True
Prelude> f 4
False
Prelude> let g = (1 `elem`) -- partial application, first operand
Prelude> g [1,2]
True
Prelude> g [2,3]
False
Yes, this is the section syntax at work.
Sections are written as ( op e ) or ( e op ), where op is a binary operator and e is an expression. Sections are a convenient syntax for partial application of binary operators.
The following identities hold:
(op e) = \ x -> x op e
(e op) = \ x -> e op x
All infix operators can be used in sections in Haskell - except for - due to strangeness with unary negation. This even includes non-infix functions converted to infix by use of backticks. You can even think of the formulation for making operators into normal functions as a double-sided section:
(x + y) -> (+ y) -> (+)
Sections are (mostly, with some rare corner cases) treated as simple lambdas. (/ 2) is the same as:
\x -> (x / 2)
and (2 /) is the same as \x -> (2 / x), for an example with a non-commutative operator.
There's nothing deeply interesting theoretically going on here. It's just syntactic sugar for partial application of infix operators. It makes code a little bit prettier, often. (There are counterexamples, of course.)

Resources