I was wondering if we can use where in an anonymous function or not. I tried to do it in this way:
\x -> k where k = x+1
But this gives a parse error on 'where'.
You can use where in certain expressions within a lambda expression, but not just inside.
f = \x ->
case x of
Nothing -> 12
Just y -> z * 2
where z = y + 7
Related
I wrote two functions. My first function receives two parameters, f a function, and n. f is arbitrary function and n is a stop value.
My first function looks like so
series f 0 = (f 0)
series f n = seriesInt f n 0 0
-- Not a main question, but how can both these functions series and
-- seriesInt be written as one function?
seriesInt f n acc i | i <= n = seriesInt f n (acc + (f i)) (i+1)
| otherwise = acc
My second function is this
taylor i x | x == 1 = 1
| otherwise = ((-1)^i / (myFac t)) * (x^t)
where
t = (2 * i + 1)
For this function I need two parameters, i and x.
Parameter i will be passed from my series function, but how can I pass parameter x to this function?
I'm supposing, I need a Lambda expression for that?
Yes, you pass it a lambda function, (\ i -> taylor i x), like so:
foo n x = seriesInt (\ i -> taylor i x) n 0 0
You could use as e.g. map (foo 1000) [1..10].
The lambda function is defined in the scope of x, so it can use it. A new lambda function is defined by the call to foo for each x that foo gets called with.
I'm currently working through The Craft of Functional Programming 2nd Edition and I have been presented with a task to write a between function which has stumped me.
The function takes three numbers as arguments and returns a boolean result i.e.
between :: Int -> Int -> Int -> Bool
It is defined so that between m n p is true if n is between n and p. For the sake of simplicity given between 2 2 2, the function would return true, also between 3 3 5 would return true.
Mathematically, x<=y and y<=z
The question also recommended that I could write a weakAscendingOrder function which checks that the number sequence doesn't go down at any point. I have written this function and my code is shown below:
weakAscendingOrder :: Int -> Int -> Int -> Bool
weakAscendingOrder x y z = (x <= y) && (y <= z)
How can I write a between function, either with or without using weakAscendingOrder, while preserving the function signatures since they have been provided by the book?
Comment two is exactly right. The weakAscendingOrder function behaves exactly like you want between to behave. Here are some additional flavors of implementation:
between x y z --using guards
|x <= y = y <= z
|otherwise = False
between x y z = if (x <= y) then (y <= z) else False --using if
between x y z = case (x <= y) of True -> (y <= z) --using case syntax
False -> False
however the (x<=y)&&(y<=z) is in my opinion very readable and does the job nicely.
I know that something like \x->x+1 is an anonymous function definition that gets an x and adds one to it. But I saw the expression return x = (\ r -> x) when I was reading an article here.
What does (\ r -> x) mean? Why after backslash is empty?
There is no difference: \ r -> x or \r -> x have the same meaning, much as 1+1 and 1 + 1 have the same meaning. Whitespace after \ is irrelevant.
So, return x is just \r -> x, which is a function which takes a parameter r, ignores it, and yields x.
Moreover, since r gets ignored, we tend to write \ _ -> x (or const x - which is defined as const x _ = x) instead.
I have written the following code:
hosum :: (Int->Int)->(Int->Int)
hosum f 0 = 1
hosum f n = afunction f (-abs(n)) (abs(n))
afunction :: (Int->Int)->Int->Int->Int
afunction f a z
|a==z
= 0
|otherwise
= afunction f (a+1) z + afunction f a z
to find the sum of f(i) from -|n| to |n|.. Where is my mistake?
As pointed out in the comments, your code never calls the f function. There are several other things in your code that I don't understand:
hosum f 0 = 1. Why is it one for any f. Shouldn't it be f 0?
In afunction, why is the result 0 if a == z. If the range is inclusive, it should be zero only if a > z.
afunction in the otherwise case calls itself twice. Why doesn't it apply f to a and calls afunction f (a + 1) z only?
Now about a correct solution.
The easiest(and idiomatic) way to implement it is to use standard sum and map functions. It gives a one-liner(if we don't count type signature):
hosum :: (Int -> Int) -> Int -> Int
hosum f n = sum $ map f [-abs(n)..abs(n)]
In plain English, this function takes a list of all numbers from -abs(n) to abs(n), applies f to each of them and sums them up. That's exactly what the problem statement tells us to do.
I want to write a Haskell program that calculates the sum of numbers between 2 given numbers.
I have the following code:
sumInt :: Int -> Int -> Int
sumInt x y
| x > y = 0
| otherwise = x + sumInt x+1 y
But when I compile it I get the following error:
SumInt is applied to too few arguments.
I don't understand what I'm doing wrong. Any ideas?
You need parentheses around x+1:
| otherwise = x + sumInt (x + 1) y
The reason is that function application binds more tightly than operators, so whenever you see
f x <> y
This is always parsed as
(f x) <> y
and never as
f (x <> y)