Explanation of a Haskell function from an old exam - function

I'm reviewing an old exam in my Haskell programming course and I can't seem to wrap my head around this function (I think there is just too little information given).
The code given is
myId x = x
function n f
| n > 0 = f . function (n-1) f
| otherwise = myId
I know that if I for example call the function with the input 2 (*2), I will get a function as result. And if I call it with (-2) (*2) 1 I will get the result 1.
I just don't know how? Also I can't wrap my head around the typecast of the function.
I know that these two options are correct but I don't understand why (probably parentheses that confuse me at the moment).
function :: (Num a, Ord a) => a -> (a -> a) -> a -> a
function :: (Num a, Ord b) => a -> (b -> b) -> b -> b
Anyone that can clarify how I should "read" this function and how I should understand how the typecast works (been reading my Programming in Haskell literature and from Learn You a Haskell but been going in circle for a few days now).

function takes some number n and a function f :: a -> a, and composes that function with itself n times, returning another function of type a -> a. When the returned function is applied to a value of type a, the result is essentially the same as executing f in a loop n times, using the output of each previous step as the input for the next.
Perhaps it is easier to see the similarity if the final parameter is made explicit:
function :: (Ord a, Num a) -> a -> (b -> b) -> b -> b
function n f x
| n > 0 = f (function (n-1) f x)
| otherwise = x
This is functionally equivalent to your point-free function.
In Haskell, a function f :: a -> b -> c can be interpreted either as "a function that takes an a and a b and returns a c" or "a function that takes an a and returns a function from b to c". When you apply a function to one or more inputs, think of each input as eliminating one of the function's arguments. In this instance, function 10 returns a new function with type (a -> a) -> a -> a, and function 2 (*2) returns a function with type Num a => a -> a.
When you think of it this way, it should hopefully be clear why function (-2) (*2) 1 returns a number while function 2 (*2) returns a function. There is no type casting going on; when you are applying the three argument function to two inputs, you get another function back instead of a value, since you didn't provide the final input needed to compute that value.

Related

Need help understanding how this Haskell code works

I am trying to learn Haskell programming language by trying to figure out some pieces of code.
I have these 2 small functions but I have no idea how to test them on ghci.
What parameters should I use when calling these functions?
total :: (Integer -> Integer) -> Integer -> Integer
total function count = foldr(\x count -> function x + count) 0 [0..count]
The function above is supposed to for the given value n, return f 0 + f 1 + ... + f n.
However when calling the function I don't understand what to put in the f part. n is just an integer, but what is f supposed to be?
iter :: Int -> (a -> a) -> (a -> a)
iter n f
| n > 0 = f . iter (n-1) f
| otherwise = id
iter' :: Int -> (a -> a) -> (a -> a)
iter' n = foldr (.) id . replicate n
This function is supposed to compose the given function f :: a -> a with itself n :: Integer times, e.g., iter 2 f = f . f.
Once again when calling the function I don't understand what to put instead of f as a parameter.
To your first question, you use any value for f such that
f 0 + f 1 + ... + f n
indeed makes sense. You could use any numeric function capable of accepting an Integer argument and returning an Integer value, like (1 +), abs, signum, error "error", (\x -> x^3-x^2+5*x-2), etc.
"Makes sense" here means that the resulting expression has type ("typechecks", in a vernacular), not that it would run without causing an error.
To your second question, any function that returns the same type of value as its argument, like (1+), (2/) etc.

How to find maximum of function outputs with multipe inputs in one function?

I want a function maxfunct, with input f (a function) and input n (int), that computes all outputs of function f with inputs 0 to n, and checks for the max value of the output.
I am quite new to haskell, what I tried is something like that:
maxfunct f n
| n < 0 = 0
| otherwise = maximum [k | k <- [\(f, x)-> f x], x<- [0..n]]
Idea is that I store every output of f in a list, and check for the maximum in this list.
How can I achieve that?
You're close. First, let's note the type of the function we're trying to write. Starting with the type, in addition to helping you get a better feel for the function, also lets the compiler give us better error messages. It looks like you're expecting a function and an integer. The result of the function should be compatible with maximum (i.e. should satisfy Ord) and also needs to have a reasonable "zero" value (so we'll just say it needs Num, for simplicity's sake; in reality, we might consider using Bounded or Monoid or something, depending on your needs, but Num will suffice for now).
So here's what I propose as the type signature.
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
Technically, we could generalize a bit more and make the Int a type argument as well (requires Num, Enum, and Ord), but that's probably overkill. Now, let's look at your implementation.
maxfunct f n
| n < 0 = 0
| otherwise = maximum [k | k <- [\(f, x)-> f x], x<- [0..n]]
Not bad. The first case is definitely good. But I think you may have gotten a bit confused in the list comprehension syntax. What we want to say is: take every value from 0 to n, apply f to it, and then maximize.
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
maxfunct f n
| n < 0 = 0
| otherwise = maximum [f x | x <- [0..n]]
and there you have it. For what it's worth, you can also do this with map pretty easily.
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
maxfunct f n
| n < 0 = 0
| otherwise = maximum $ map f [0..n]
It's just a matter of which you find more easily readable. I'm a map / filter guy myself, but lots of folks prefer list comprehensions, so to each his own.

How do I declare an 'operator' that takes 2 arguments and uses letters rather than symbols?

I want to be able to make operators such as found in VB(.net) like shown below
Console.WriteLine ( 16 Mod 2 )
produces an output shown below
0
As you can see, this makes code slightly easier to read. How would I go about making functions that do this?
I have tried the following format
equal :: Integer -> Integer -> bool
x `equal` y = x == y
and I get the following error
*Main> 5 equal 5
<interactive>:1:1: error:
* Non type-variable argument
in the constraint: Num ((Integer -> Integer -> Bool) -> t -> t1)
(Use FlexibleContexts to permit this)
* When checking the inferred type
it :: forall t t1.
(Num ((Integer -> Integer -> Bool) -> t -> t1), Num t) =>
t1
*Main>
What is going wrong and how do I do it correctly?
You need to use backticks around equal when you call it, exactly as you did to define it.
5 `equal` 5
The way you wrote it, Haskell thinks you're trying to pass equal as an argument to 5, rather than the other way around.

Use of function application operator in Haskell

What does the following expression means in haskell?
($ 3)
ghci shows the following type
($ 3) :: Num a => (a -> b) -> b.
($ 3) is a section, and is equivalent to \f -> f 3, which takes a function argument and applies it to 3.
If we considered 3 to be an integer, we would have that the type of f is Int -> b (for any b), so the type of ($ 3) would be (Int -> b) -> b.
Things in Haskell are a bit more complex, since 3 can be of any numeric type, so we don't really need f :: Int -> b, it's enough if f :: a -> b where a is a numeric type.
Hence we get ($ 3) :: Num a => (a -> b) -> b.
(# x) for any operator # is equivalent to \a -> a # x; so ($ 3) is equivalent to \f -> f $ 3, i.e. a function that applies any function you pass it to 3. This syntax is called "sections".
> let f = ($ 3)
> f show
"3"
> f square
9
Another way to look at it is
($) :: (a -> b) -> a -> b
3 :: Num a => a
and when you "insert 3" in the ($) it will become
($ 3) :: Num a => (a -> b) -> b.
due to that you no longer need to supply the a, but the function you need to supply is now restricted to num, since the 3 can be any numeric type.
This is at least how I look at functions in Haskell, like substitution in algebra.

passing a function with an arbitrary amount of parameters

I've recently been learning haskell from this awesome site, and I just learned about passing functions as parameters in the Higher Order Functions chapter. I can see how passing functions as parameters can be extremely useful, but from my current(lowley) understanding you need to specify the amount of parameters in this function, which can be quite limited given this function:
--takes a function and returns a function that has flipped arguments
flip' :: (a -> b -> c) -> (b -> a -> c) --very limited
flip' f = g
where g x y = f y x
useful, but only to the point of functions taking two parameters, is there a way to write a function definition that accepts functions with an arbitrary amount of parameters? My guess would have to be some sort of parameter list, but I can't seem to find any information on it. Thanks!
Actually flip works with functions with more than two parameters, but might not be exactly what you need:
Prelude> :t (,,,)
(,,,) :: a -> b -> c -> d -> (a, b, c, d)
Prelude> :t flip (,,,)
flip (,,,) :: b -> a -> c -> d -> (a, b, c, d)
since
(,,,) :: a -> b -> c -> d -> (a, b, c, d)
is
(,,,) :: a -> (b -> (c -> (d -> (a, b, c, d))))
the first two parameters get flipped. Here a is a, b is b, but c is c -> d -> (a, b, c, d).
And then again, what do you expect to achieve by flipping a 3 parameter function like in this example?
EDIT: And also, there are vararg functions - one example is printf. This Haskell.org page is pretty nice. In short, some typeclass magic could be used to achieve this effect.