How to find maximum of function outputs with multipe inputs in one function? - 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.

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.

Count number of odd digits in Integer Haskell

I'm trying to make program which counts the number of odd digits in integer using Haskell. I have ran into problem with checking longer integers. My program looks like this at the moment:
oddDigits:: Integer -> Int
x = 0
oddDigits i
| i `elem` [1,3,5,7,9] = x + 1
| otherwise = x + 0
If my integer is for example 22334455 my program should return value 4, because there are 4 odd digits in that integer. How can I check all numbers in that integer? Currently it only checks first digit and returns 1 or 0. I'm still pretty new to haskell.
You can first convert the integer 22334455 to a list "22334455". Then find all the elements satisfying the requirement.
import Data.List(intersect)
oddDigits = length . (`intersect` "13579") . show
In order to solve such problems, you typically split this up into smaller problems. A typical pipeline would be:
split the number in a list of digits;
filter the digits that are odd; and
count the length of the resulting list.
You thus can here implement/use helper functions. For example we can generate a list of digits with:
digits' :: Integral i => i -> [i]
digits' 0 = []
digits' n = r : digits' q
where (q, r) = quotRem n 10
Here the digits will be produced in reverse order, but since that does not influences the number of digits, that is not a problem. I leave the other helper functions as an exercise.
Here's an efficient way to do that:
oddDigits :: Integer -> Int
oddDigits = go 0
where
go :: Int -> Integer -> Int
go s 0 = s
go s n = s `seq` go (s + fromInteger r `mod` 2) q
where (q, r) = n `quotRem` 10
This is tail-recursive, doesn't accumulate thunks, and doesn't build unnecessary lists or other structures that will need to be garbage collected. It also handles negative numbers correctly.

How can two similar functions have different polymorphic types in Haskell?

Im pretty much new to Haskell, so if Im missing key concept, please point it out.
Lets say we have these two functions:
fact n
| n == 0 = 1
| n > 0 = n * (fact (n - 1))
The polymorphic type for fact is (Eq t, Num t) => t -> t Because n is used in the if condition and n must be of valid type to do the == check. Therefor t must be a Number and t can be of any type within class constraint Eq t
fib n
| n == 1 = 1
| n == 2 = 1
| n > 2 = fib (n - 1) + fib (n - 2)
Then why is the polymorphic type of fib is (Eq a, Num a, Num t) => a -> t?
I don't understand, please help.
Haskell always aims to derive the most generic type signature.
Now for fact, we know that the type of the output, should be the same as the type of the input:
fact n | n == 0 = 1
| n > 0 = n * (fact (n - 1))
This is due to the last line. We use n * (fact (n-1)). So we use a multiplication (*) :: a -> a -> a. Multiplication thus takes two members of the same type and returns a member of that type. Since we multiply with n, and n is input, the output is of the same type as the input. Since we use n == 0, we know that (==) :: Eq a => a -> a -> Bool so that means that that input type should have Eq a =>, and furthermore 0 :: Num a => a. So the resulting type is fact :: (Num a, Eq a) => a -> a.
Now for fib, we see:
fib n | n == 1 = 1
| n == 2 = 1
| n > 2 = fib (n - 1) + fib (n - 2)
Now we know that for n, the type constraints are again Eq a, Num a, since we use n == 1, and (==) :: Eq a => a -> a -> Bool and 1 :: Num a => a. But the input n is never directly used in the output. Indeed, the last line has fib (n-1) + fib (n-2), but here we use n-1 and n-2 as input of a new call. So that means we can safely asume that the input type and the output type act independently. The output type, still has a type constraint: Num t: this is since we return 1 for the first two cases, and 1 :: Num t => t, and we also return the addition of two outputs: fib (n-1) + fib (n-2), so again (+) :: Num t => t -> t -> t.
The difference is that in fact, you use the argument directly in an arithmetic expression which makes up the final result:
fact n | ... = n * ...
IOW, if you write out the expanded arithmetic expression, n appears in it:
fact 3 ≡ n * (n-1) * (n-2) * 1
This fixes that the argument must have the same type as the result, because
(*) :: Num n => n -> n -> n
Not so in fib: here the actual result is only composed of literals and of sub-results. IOW, the expanded expression looks like
fib 3 ≡ (1 + 1) + 1
No n in here, so no unification between argument and result required.
Of course, in both cases you also used n to decide how this arithmetic expression looks, but for that you've just used equality comparisons with literals, whose type is not connected to the final result.
Note that you can also give fib a type-preservig signature: (Eq a, Num a, Num t) => a -> t is strictly more general than (Eq t, Num t) => t -> t. Conversely, you can make a fact that doesn't require input- and output to be the same type, by following it with a conversion function:
fact' :: (Eq a, Integral a, Num t) => a -> t
fact' = fromIntegral . fact
This doesn't make a lot of sense though, because Integer is pretty much the only type that can reliably be used in fact, but to achieve that in the above version you need to start out with Integer. Hence if anything, you should do the following:
fact'' :: (Eq t, Integral a, Num t) => a -> t
fact'' = fact . fromIntegral
This can then be used also as Int -> Integer, which is somewhat sensible.
I'd recommend to just keep the signature (Eq t, Num t) => t -> t though, and only add conversion operations where it's actually needed. Or really, what I'd recommend is to not use fact at all – this is a very expensive function that's hardly ever really useful in practice; most applications that naïvely end up with a factorial really just need something like binomial coefficients, and those can be implemented more efficiently without a factorial.

Haskell Integer Odd Digits Checker

I seem to be stuck on a question and have no idea how to approach it or what Im doing wrong with my current code.
I have to write a function called oddDigits which takes a single integer argument and returns a boolean result. It should return True if and only if the argument is a positive integer with an odd number of digits. If the argument is zero or negative, the function should stop with an error message.
Also, cant convert the argument into a string. Have to use recursion.
I have a feeling each digit could be stored in a list recursively and then the length of the list could determine the answer.
So far, I have this:
oddDigits :: Integer -> Bool
lst = []
oddDigits x
| (x < 0) || (x == 0) = error
| x `mod` 10 ++ lst ++ oddDigits(x `div` 10)
| length(lst) `mod` 2 /= 0 = True
| otherwise = False
Sorry if the code looks horrible. I am new to Haskell and still learning. What exactly am I doing wrong and how could I correct it?
First off, this seems a pretty weird thing to check. Perhaps what you're doing wrong is to ever consider this problem...
But if you persist you want to know the property of an integer having an odd number of digits... oh well. There's a lot that could be improved. For starters, (x < 0) || (x == 0) doesn't need the parentheses – < and == (infix 4) bind more tightly than ||. If you're not sure about this, you can always ask GHCi:
Prelude> :i ==
class Eq a where
(==) :: a -> a -> Bool
...
-- Defined in ‘GHC.Classes’
infix 4 ==
Prelude> :i ||
(||) :: Bool -> Bool -> Bool -- Defined in ‘GHC.Classes’
infixr 2 ||
But here you don't need || anyway because there's a dedicated operator for less-than-or-equal. Hence you can just write
oddDigits x
| x <= 0 = error "bla bla"
| ...
Then, you can “convert” the number to a string. Converting to string is generally a really frowned-upon thing to do because it throws all structure, typechecking etc. out of the window; however “number of digits” basically is a property of a string (the decimal expansion), rather than a number itself, so this is not entirely unsensible for this specific task. This would work:
oddDigits x
| x <= 0 = error "blearg"
| length (show x)`mod`2 /= 0 = True
| otherwise = False
however it's a bit redundancy department redundant. You're checking if something is True, then give True as the result... why not just put it in one clause:
oddDigits x
| x <= 0 = error "blearg"
| otherwise = length (show x)`mod`2 /= 0
That's perhaps in fact the best implementation.
For any proper, sensible task, I would not recommend going the string route. Recursion is better. Here's what it could look like:
oddDigits 1 = True
oddDigits x
| x <= 0 = error "blearg"
| otherwise = not . oddDigits $ x`div`10
There's nothing wrong with your general approach of converting to a list of digits, then finding the length of the list. Really where you went wrong is trying to cram everything into one function. As you found out first hand, it makes it very difficult to debug. Functional programming works best with very small functions.
If you separate out the responsibility of converting an integer to a list of digits, using a digs function like the one from this answer, the rest of your algorithm simplifies to:
oddDigits x | x <= 0 = error
oddDigits x = odd . length $ digs x
leftaroundabout's eventual answer is very nice, however it fails for numbers like 2,3 and 23. Here's a fix.
oddDigits x
| x <= 0 = error "blearg"
| x < 10 = True
| otherwise = not . oddDigits $ x`div`10
Its much more elegant than my initial answer, below. I'm including it to introduce a common functional paradigm, a worker/wrapper transformation of the problem. Here the wrapper gives the interface and passes off the work to another function. Notice that the negativity check only needs to be done once now.
oddDigits :: Integer -> Bool
oddDigits x
| x <= 0 = False
| otherwise = oddDigits' True x
oddDigits' :: Bool -> Integer -> Bool
oddDigits' t x
| x < 10 = t
| otherwise = oddDigits' (not t) $ x `div` 10
oddDigits' carries a piece of internal data with it, the initial Bool. My first first thought was to have that Bool be a digit accumulator, counting the number of digits. In that case, an "unwrapper" needs to be supplied, in this case the standard "odd" function:
oddDigits x
| x <= 0 = False
| otherwise = odd . oddDigits'' 1 $ x
where oddDigits'' :: Integer -> Integer -> Integer.

Explanation of a Haskell function from an old exam

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.