argmax function in Haskell [duplicate] - haskell

I am trying to write a One line function where you enter a number and a List, and it returns the highest value.
For example:
Input: getMax 5 [1,4,7]
Output: 7
Here is my current code:
getMax :: (Ord a) => a -> [a] -> a
getMax f xs = foldr max f xs
Now I want to extend my function so that instead of a number I can enter a Lamda function to be compared.
For example:
Input: getMax (\x -> mod x 5) [1,4,7]
Output: 4
But I cannot get it to work.
I get an error message:
No instance for (Show (Integer -> Integer))
which I don't really understand.
I tried to change the type signature, but that did not help.
thanks in advance!

Your foldr function should work with f, and pick one of the two items x₁ or x₂ based on whether f x₁ is less than or equal to f x₂, so:
getMax :: Ord b => (a -> b) -> [a] -> a
getMax f xs = foldr1 g xs
where g x₁ x₂
| … = …
| otherwise = …
where I leave implementing the … parts as an exercise.

Related

Haskell - Check if position is even/odd

What I need to do is to apply alternately 2 functions in a list. For example:
(*2) (-3) [4,5,6,7,8]
would result in
[8,2,12,4,16], because 4*2, 5-3, 6*2, 7-3, 8*2...
What I was thinking was
funct :: (a -> b) -> (a -> b) -> [a] -> [b]
and then something like
[f x | x <- xs] however I won't have just "f", but will have the other function as well.
So I was thinking about checking the position of x. If it is an even position, then f x. Otherwise g x.
Could someone help me?
Tks.
You do not really need the index, what you need is a list that alternates between (*2) and (-3). We can make use of cycle :: [a] -> [a] and zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]. We can thus use:
zipWith ($) (cycle [(2*), subtract 3]) [4,5,6,7,8]
Here ($) :: (a -> b) -> a -> b is used to perform a function application. So ($) f x is equivalent to f x.
This gives the expected:
Prelude> zipWith ($) (cycle [(2*), subtract 3]) [4,5,6,7,8]
[8,2,12,4,16]
You could always write this out with explicit recursion, to be completely clear about how it works:
alternateFunctions _ _ [] = []
alternateFunctions f g (x:xs) = f x:alternateFunctions g f xs
For an empty list, there's nothing to do. Otherwise, apply the first function to the first element, and recurse for the rest of the list with the first and second functions switched. With that, you have alternateFunctions (*2) (subtract 3) [4,5,6,7,8] = [8,2,12,4,16], as desired.
If you care about performance, then you should rewrite this as a foldr, so that it can fuse:
alternateFunctions f g xs = foldr go mempty xs f g
where go x acc f g = f x:acc g f

How would you declare the types of these functions in Haskell?

So I'm learning about Haskell at the moment, and I came across this question:
The type of a function f is supposed to be a->[a]->a. The
following definitions of f are incorrect because their types are all
different from a->[a]->a:
i. f x xs = xs
ii. f x xs = x+1
iii. f x xs = x ++ xs
iv. f x (y:ys) = y
My answers as I see it are:
i) f :: a -> a -> a
This is because x or xs can be of any value and is not a list as it does not contain the ':' operator.
ii) f :: Int -> a -> Int
This is because the + operator is used on x, meaning x is of type Int.
iii) f :: Eq a => a -> a -> a
The ++ operators are used, therefore in order to concatenate they must be of the same type..?
iv) f :: a -> [a] -> a
f returns an element from the list.
The last one is definitely wrong, because it can't be of type a -> [a] -> a. Are there any others I did wrong, and why? I'm hoping I can fully understand types and how to find out the types of functions.
i) f :: a -> a -> a
f x xs = xs
This is because x or xs can be of any value and is not a list as it does not contain the ':' operator.
True, but it also does not have to be of the same type!
So, it's actually f :: a -> b -> b.
ii) f :: Int -> a -> Int
f x xs = x+1
This is because the + operator is used on x, meaning x is of type Int.
Correct. (Actually, in Haskell we get Num b => b -> a -> b which generalized the Int to any numeric type, but it's not that important.)
iii) f :: Eq a => a -> a -> a
f x xs = x ++ xs
The ++ operators are used, therefore in order to concatenate they must be of the same type..?
True, but they must be lists. Also, Eq is only needed if you use == or something which compares values.
Here, f :: [a] -> [a] -> [a].
iv) f :: a -> [a] -> a
f x (y:ys) = y
f returns an element from the list.
The type of x does not have to be the same. We get f :: b -> [a] -> a.
i. f x xs = xs
(...)
i) f :: a -> a -> a
Although this can be a type signature, you make it too restrictive. The function takes two parameters x and xs. Initially we can reason that x and xs can have different types, so we say that x :: a, and xs :: b. Since the function returns xs, the return type is b as well, so the type is:
f :: a -> b -> b
f x xs = xs
ii. f x xs = x+1
(...)
ii) f :: Int -> a -> Int
Again you make the function too restrictive. Let us again assume that x :: a and xs :: b have different types. We see that we return x + 1 (or in more canonical form (+) x 1. Since (+) has signature (+) :: Num c => c -> c -> c (we here use c since a is already used), and 1 has signature 1 :: Num d => d, we thus see that we call (+) with x and 1, as a result we know that a ~ c (a and c are the same type), and c ~ d, so as a result we obtain the signature:
f :: Num c => c -> b -> c
f x xs = x+1
iii. f x xs = x ++ xs
(...)
iii) f :: Eq a => a -> a -> a
This is wrong: we here see that f has two parameters, x :: a and xs :: b. We see that we return (++) x xs. Since (++) has signature (++) :: [c] -> [c] -> [c], we thus know that a ~ [c] and b ~ [c], so the type is:
f :: [c] -> [c] -> [c]
f x xs = x ++ xs
iv. f x (y:ys) = y
(...)
iv) f :: a -> [a] -> a
This is again too restrictive. Here we see again two parameters: x and (y:ys). We first generate a type a for x :: a, and (y:ys) :: b, since the pattern of the second parameter is (y:ys), this is a list constructor with as parameters (:) :: c -> [c] -> [c]. As a result we can derive that y :: c, and ys :: [c], furthermore the pattern (y:ys) has type [c]. Since the function returns y, we know that the return type is c, so:
f :: a -> [c] -> c
f x (y:ys) = y
Note: you can let Haskell derive the type of the function itself. In GHCi you can use the :t command to query the type of an expression. For example:
Prelude> f x (y:ys) = y
Prelude> :t f
f :: t1 -> [t] -> t

haskell function that sums AND multiplies numbers of a list

I'm trying to do a function that given an operator and a function will go through a list like such:
reduce (*) even [1,2,3,4,5] => 8
reduce (+) odd [1,2,3,4,5] => 9
At first I had something like this:
reduce :: (Int-> Int-> Int) -> (Int->Bool) -> [Int] -> Int
reduce op x y = foldl op 1 (filter x y)
and it worked fine for multiplying, but added one number when trying to do a sum. So I thought of adding an if:
reduce :: (Int-> Int-> Int) -> (Int->Bool) -> [Int] -> Int
reduce op x y =
if op == (*) then foldl op 1 (filter x y)
else if op == (+) then foldl op 0 (filter x y)
else 0
However when I do this I get the following error:
Instance of Eq (Int -> Int -> Int) required for definition of reduce
What does it mean exactly? Any ideas? Thanks in advance
It means that with your current imports you cannot compare functions for equality (and even with suitable imports, there is no really good way to do the equality you ask for).
One simple solution is to demand that the user provide both the operation and the unit, thus:
reduce op u x y = foldl op u (filter x y)
In many cases of interest, there is already a Monoid instance that specifies the operator and unit. For example, there are the Sum and Product instances, so you might consider writing
reduce inject p = foldMap inject . filter p
which would be used like this:
> reduce Sum even [1..5]
Sum {getSum = 6}
> reduce Product odd [1..5]
Product {getProduct = 15}
What does it mean exactly? Any ideas? Thanks in advance
You're trying to compare some (Int -> Int -> Int) to another one. But functions cannot get checked on equality. Provide the initial value instead:
reduce :: (Int -> Int -> Int) -> (Int -> Bool) -> Int -> [Int] -> Int
reduce op f x xs = foldl op x (filter f xs)
By the way, you can generalize your function's type:
reduce :: (b -> a -> b) -> (a -> Bool) -> b -> [a] -> a
reduce op f x xs = foldl op x (filter f xs)
Alternatively, use a monoid and foldMap.

Does haskell's foldr always take a two-parameter lambda?

Haskell newb here
I'm working on this problem in haskell:
(**) Eliminate consecutive duplicates of list elements.
If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed.
Example:
* (compress '(a a a a b c c a a d e e e e))
(A B C A D E)
The solution (which I had to look up) uses foldr:
compress' :: (Eq a) => [a] -> [a]
compress' xs = foldr (\x acc -> if x == (head acc) then acc else x:acc) [last xs] xs
This foldr, according to the solution, takes two parameters, x and acc. It would seem like all foldr's take these parameters; is there any exception to this? Like a foldr that takes 3 or more? If not, is this convention redundant and can the formula be written with less code?
foldr takes a function of 2 arguments, but this doesn't prevent it from taking a function of 3 arguments provided that function has the right type signature.
If we had a function
g :: x -> y -> z -> w
With
foldr :: (a -> b -> b) -> b -> [a] -> b
Where we want to pass g to foldr, then (a -> b -> b) ~ (x -> y -> z -> w) (where ~ is type equality). Since -> is right associative, this means we can write g's signature as
x -> y -> (z -> w)
and its meaning is the same. Now we've produced a function of two parameters that returns a function of one parameter. In order to unify this with the type a -> b -> b, we just need to line up the arguments:
a -> | x ->
b -> | y ->
b | (z -> w)
This means that b ~ z -> w, so y ~ b ~ z -> w and a ~ x so g's type really has to be
g :: x -> (z -> w) -> (z -> w)
implying
foldr g :: (z -> w) -> [x] -> (z -> w)
This is certainly not impossible, although more unlikely. Our accumulator is a function instead, and to me this begs to be demonstrated with DiffLists:
type DiffList a = [a] -> [a]
append :: a -> DiffList a -> DiffList a
append x dl = \xs -> dl xs ++ [x]
reverse' :: [a] -> [a]
reverse' xs = foldr append (const []) xs $ []
Note that foldr append (const []) xs returns a function which we apply to [] to reverse a list. In this case we've given an alias to functions of the type [a] -> [a] called DiffList, but it's really no different than having written
append :: a -> ([a] -> [a]) -> [a] -> [a]
which is a function of 3 arguments.
As with all things in haskell have a look at the types of things to guide your way you can do this for any function in ghci.
Looking at this for foldr we see:
Prelude> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
This slightly abstract string can be written in english as:
foldr is a function that takes
1 ) a function with two parameters one of type a and one of type b and returns something of type b
2 ) A value of type b
3 ) A list of values of type a
And returns a value of type b
Where a and b are type variables (see here for a good tutorial on them) which can be filled in with any type you like.
It turns out that you can solve your compress problem using a foldr with a three-argument function.
compress :: Eq a => [a] -> [a]
compress [] = []
compress (z:zs) = z : foldr f (const []) zs z
where f x k w | x==w = k x
| otherwise = x : k x
Let's dissect that. First, we can improve readability by changing the last two lines to
where f x k = \w -> if x==w then k x else x : k x
This makes it evident that a ternary function is nothing but a binary function returning a unary function. The advantage of looking at it in this way is that foldr is best understood when passed a binary function. Indeed, we are passing a binary function, which just happens to return a function.
Let's focus on types now:
f :: a -> (a -> [a]) -> (a -> [a])
f x k
So, x::a is the element of the list we are folding on. Function k is the result of the fold on the list tail. The result of f x k is something having the same type as k.
\w -> if .... :: (a -> [a])
The overall idea behind this anonymous function is as follows. The parameter k plays the same role as acc in the OP code, except it is a function expecting the previous element w in the list before producing the accumulated compressed list.
Concretely, we use now k x when we used acc, passing on the current element to the next step, since by that time x will become the previous element w. At the top-level, we pass z to the function which is returned by foldr f (const []).
This compress variant is lazy, unlike the posted solution. In fact, the posted solution needs to scan the whole list before starting producing something: this is due to (\x acc -> ...) being strict in acc, and to the use of last xs. Instead, the above compress outputs list elements in a "streaming" fashion. Indeed, it works with infinite lists as well:
> take 10 $ compress [1..]
[1,2,3,4,5,6,7,8,9,10]
That being said, I think using a foldr here feels a bit weird: the code above is arguably less readable than the explicit recursion.

Project Euler 3 - Haskell

I'm working my way through the Project Euler problems in Haskell. I have got a solution for Problem 3 below, I have tested it on small numbers and it works, however due to the brute force implementation by deriving all the primes numbers first it is exponentially slow for larger numbers.
-- Project Euler 3
module Main
where
import System.IO
import Data.List
main = do
hSetBuffering stdin LineBuffering
putStrLn "This program returns the prime factors of a given integer"
putStrLn "Please enter a number"
nums <- getPrimes
putStrLn "The prime factors are: "
print (sort nums)
getPrimes = do
userNum <- getLine
let n = read userNum :: Int
let xs = [2..n]
return $ getFactors n (primeGen xs)
--primeGen :: (Integral a) => [a] -> [a]
primeGen [] = []
primeGen (x:xs) =
if x >= 2
then x:primeGen (filter (\n->n`mod` x/=0) xs)
else 1:[2]
--getFactors
getFactors :: (Integral a) => a -> [a] -> [a]
getFactors n xs = [ x | x <- xs, n `mod` x == 0]
I have looked at the solution here and can see how it is optimised by the first guard in factor. What I dont understand is this:
primes = 2 : filter ((==1) . length . primeFactors) [3,5..]
Specifically the first argument of filter.
((==1) . length . primeFactors)
As primeFactors is itself a function I don't understand how it is used in this context. Could somebody explain what is happening here please?
If you were to open ghci on the command line and type
Prelude> :t filter
You would get an output of
filter :: (a -> Bool) -> [a] -> [a]
What this means is that filter takes 2 arguments.
(a -> Bool) is a function that takes a single input, and returns a Bool.
[a] is a list of any type, as longs as it is the same type from the first argument.
filter will loop over every element in the list of its second argument, and apply it to the function that is its first argument. If the first argument returns True, it is added to the resulting list.
Again, in ghci, if you were to type
Prelude> :t (((==1) . length . primeFactors))
You should get
(((==1) . length . primeFactors)) :: a -> Bool
(==1) is a partially applied function.
Prelude> :t (==)
(==) :: Eq a => a -> a -> Bool
Prelude> :t (==1)
(==1) :: (Eq a, Num a) => a -> Bool
It only needs to take a single argument instead of two.
Meaning that together, it will take a single argument, and return a Boolean.
The way it works is as follows.
primeFactors will take a single argument, and calculate the results, which is a [Int].
length will take this list, and calculate the length of the list, and return an Int
(==1) will
look to see if the values returned by length is equal to 1.
If the length of the list is 1, that means it is a prime number.
(.) :: (b -> c) -> (a -> b) -> a -> c is the composition function, so
f . g = \x -> f (g x)
We can chain more than two functions together with this operator
f . g . h === \x -> f (g (h x))
This is what is happening in the expression ((==1) . length . primeFactors).
The expression
filter ((==1) . length . primeFactors) [3,5..]
is filtering the list [3, 5..] using the function (==1) . length . primeFactors. This notation is usually called point free, not because it doesn't have . points, but because it doesn't have any explicit arguments (called "points" in some mathematical contexts).
The . is actually a function, and in particular it performs function composition. If you have two functions f and g, then f . g = \x -> f (g x), that's all there is to it! The precedence of this operator lets you chain together many functions quite smoothly, so if you have f . g . h, this is the same as \x -> f (g (h x)). When you have many functions to chain together, the composition operator is very useful.
So in this case, you have the functions (==1), length, and primeFactors being compose together. (==1) is a function through what is called operator sections, meaning that you provide an argument to one side of an operator, and it results in a function that takes one argument and applies it to the other side. Other examples and their equivalent lambda forms are
(+1) => \x -> x + 1
(==1) => \x -> x == 1
(++"world") => \x -> x ++ "world"
("hello"++) => \x -> "hello" ++ x
If you wanted, you could re-write this expression using a lambda:
(==1) . length . primeFactors => (\x0 -> x0 == 1) . length . primeFactors
=> (\x1 -> (\x0 -> x0 == 1) (length (primeFactors x1)))
Or a bit cleaner using the $ operator:
(\x1 -> (\x0 -> x0 == 1) $ length $ primeFactors x1)
But this is still a lot more "wordy" than simply
(==1) . length . primeFactors
One thing to keep in mind is the type signature for .:
(.) :: (b -> c) -> (a -> b) -> a -> c
But I think it looks better with some extra parentheses:
(.) :: (b -> c) -> (a -> b) -> (a -> c)
This makes it more clear that this function takes two other functions and returns a third one. Pay close attention the the order of the type variables in this function. The first argument to . is a function (b -> c), and the second is a function (a -> b). You can think of it as going right to left, rather than the left to right behavior that we're used to in most OOP languages (something like myObj.someProperty.getSomeList().length()). We can get this functionality by defining a new operator that has the reverse order of arguments. If we use the F# convention, our operator is called |>:
(|>) :: (a -> b) -> (b -> c) -> (a -> c)
(|>) = flip (.)
Then we could have written this as
filter (primeFactors |> length |> (==1)) [3, 5..]
And you can think of |> as an arrow "feeding" the result of one function into the next.
This simply means, keep only the odd numbers that have only one prime factor.
In other pseodo-code: filter(x -> length(primeFactors(x)) == 1) for any x in [3,5,..]

Resources