Haskell / Miranda: Find the type of the function - haskell

Brief: This is a past exam question from a Miranda exam but the syntax is very similar to Haskell.
Question: What is the type of the following expression and what does it do? (The definitions
of the functions length and swap are given below).
(foldr (+) 0) . (foldr ((:) . length . (swap (:) [] )) [])
length [] = 0
length (x:xs) = 1 + length xs
swap f x y = f y x
Note:
Please feel free to reply in haskell syntax - sorry about putting using the stars as polytypes but i didn't want to translate it incorrectly into haskell. Basically, if one variable has type * and the other has * it means they can be any type but they must both be the same type. If one has ** then it means that it can but does not need to have the same type as *. I think it corresponds to a,b,c etc in haskell usuage.
My working so far
From the definition of length you can see that it finds the length of a list of anything so this gives
length :: [*] -> num.
From the definition I think swap takes in a function and two parameters and produces the function with the two parameters swapped over, so this gives
swap :: (* -> ** -> ***) -> ** -> [*] -> ***
foldr takes a binary function (like plus) a starting value and list and folds the list from right to left using that function. This gives
foldr :: (* -> ** -> **) -> ** -> [*] -> **)
I know in function composition it is right associative so for example everything to the right of the first dot (.) needs to produce a list because it will be given as an argument to the first foldr.
The foldr function outputs a single value ( the result of folding up the list) so I know that the return type is going to be some sort of polytype and not a list of polytype.
My problem
I'm unsure where to go from here really. I can see that swap needs to take in another argument, so does this partial application imply that the whole thing is a function? I'm quite confused!

You've already got the answer, I'll just write down the derivation step by step so it's easy to see all at once:
xxf xs = foldr (+) 0 . foldr ((:) . length . flip (:) []) [] $ xs
= sum $ foldr ((:) . length . (: [])) [] xs
= sum $ foldr (\x -> (:) (length [x])) [] xs
= sum $ foldr (\x r -> length [x]:r) [] xs
= sum $ map (\x -> length [x] ) xs
= sum [length [x] | x <- xs]
= sum [ 1 | x <- xs]
-- = length xs
xxf :: (Num n) => [a] -> n
So that, in Miranda, xxf xs = #xs. I guess its type is :: [*] -> num in Miranda syntax.
Haskell's length is :: [a] -> Int, but as defined here, it is :: (Num n) => [a] -> n because it uses Num's (+) and two literals, 0 and 1.
If you're having trouble visualizing foldr, it is simply
foldr (+) 0 (a:(b:(c:(d:(e:(...:(z:[])...))))))
= a+(b+(c+(d+(e+(...+(z+ 0)...)))))
= sum [a, b, c, d, e, ..., z]

Let's go through this step-by-step.
The length function obviously has the type that you described; in Haskell it's Num n => [a] -> n. The equivalent Haskell function is length (It uses Int instead of any Num n).
The swap function takes a function to invoke and reverses its first two arguments. You didn't get the signature quite right; it's (a -> b -> c) -> b -> a -> c. The equivalent Haskell function is flip.
The foldr function has the type that you described; namely (a -> b -> b) -> b -> [a] -> b. The equivalent Haskell function is foldr.
Now, let's see what each sub expression in the main expression means.
The expression swap (:) [] takes the (:) function and swaps its arguments. The (:) function has type a -> [a] -> [a], so swapping it yields [a] -> a -> [a]; the whole expression thus has type a -> [a] because the swapped function is applied to []. What the resulting function does is that it constructs a list of one item given that item.
For simplicity, let's extract that part into a function:
singleton :: a -> [a]
singleton = swap (:) []
Now, the next expression is (:) . length . singleton. The (:) function still has type a -> [a] -> [a]; what the (.) function does is that it composes functions, so if you have a function foo :: a -> ... and a function bar :: b -> a, foo . bar will have type b -> .... The expression (:) . length thus has type Num n => [a] -> [n] -> [n] (Remember that length returns a Num), and the expression (:) . length . singleton has type Num => a -> [n] -> [n]. What the resulting expression does is kind of strange: given any value of type a and some list, it will ignore the a and prepend the number 1 to that list.
For simplicity, let's make a function out of that:
constPrependOne :: Num n => a -> [n] -> [n]
constPrependOne = (:) . length . singleton
You should already be familiar with foldr. It performs a right-fold over a list using a function. In this situation, it calls constPrependOne on each element, so the expression foldr constPrependOne [] just constructs a list of ones with equal length to the input list. So let's make a function out of that:
listOfOnesWithSameLength :: Num n => [a] -> [n]
listOfOnesWithSameLength = foldr constPrependOne []
If you have a list [2, 4, 7, 2, 5], you'll get [1, 1, 1, 1, 1] when applying listOfOnesWithSameLength.
Then, the foldr (+) 0 function is another right-fold. It is equivalent to the sum function in Haskell; it sums the elements of a list.
So, let's make a function:
sum :: Num n => [n] -> n
sum = foldr (+) 0
If you now compose the functions:
func = sum . listOfOnesWithSameLength
... you get the resulting expression. Given some list, it creates a list of equal length consisting of only ones, and then sums the elements of that list. It does in other words behave exactly like length, only using a much slower algorithm. So, the final function is:
inefficientLength :: Num n => [a] -> n
inefficientLength = sum . listOfOnesWithSameLength

Related

Using Haskell's foldr

I'm learning Haskell and I've been wrestling with this problem:
Write func :: (a -> Bool) -> [a] -> [a] (take elements of a list until the predicate is false) using foldr
This is what I have so far:
func :: (a -> Bool) -> [a] -> [a]
func f li = foldr f True li
and got the following errors:
Couldn't match expected type ‘[a]’ with actual type ‘Bool’
and
Couldn't match type ‘Bool’ with ‘Bool -> Bool’
Expected type: a -> Bool -> Bool
Actual type: a -> Bool
I'm a bit confused since I learned foldr by passing a function with two arguments and getting a single value. For example I've used the function by calling
foldr (\x -> \y -> x*y*5) 1 [1,2,3,4,5]
to get a single value but not sure how it works when passing a single argument function into foldr and getting a list in return. Thank you very much.
Let’s do an easier case first, and write a function that uses foldr to do nothing (to break down the list and make a the same list). Let’s look at the type signature of foldr:
foldr :: (a -> b -> b) -> b -> [a] -> [b]
And we want to write an expression of the form
foldr ?1 ?2 :: [a] -> [a]
Now this tells us that (in the signature of foldr) we can replace b with [a].
A thing we haven’t worked out, ?2, is what we replace the end of the list with and it has type b = [a]. We don’t really have anything of type a so let’s just try the most stupid thing we can:
foldr ?1 []
And now the next missing thing: we have ?1 :: a -> [a] -> [a]. Let’s write a function for this. Now there are two reasonable things we can do with a list of things and another thing and nothing else:
Add it to the start
Add it to the end
I think 1 is more reasonable so let’s try that:
myFunc = foldr (\x xs -> x : xs) []
And now we can try it out:
> myFunc [1,2,3,4]
[1,2,3,4]
So what is the intuition for foldr here? Well one way to think of it is that the function passed gets put into your list instead of :, with the other item replacing [] so we get
foldr f x [1,2,3,4]
——>
foldr f x (1:(2:(3:(4:[]))))
——>
f 1 (f 2 (f 3 (f 4 x)))
So how can we do what we want (essentially implement takeWhile with foldr) by choosing our function carefully? Well there are two cases:
The predicate is true on the item being considered
The predicate is false for the item being considered
In case 1 we need to include our item in the list, and so we can try doing things like we did with our identity function above.
In case 2, we want to not include the item, and not include anything after it, so we can just return [].
Suppose our function does the right thing for the predicate "less than 3", here is how we might evaluate it:
f 1 (f 2 (f 3 (f 4 x)))
--T T F F (Result of predicate)
-- what f should become:
1 : (2 : ([] ))
——>
[1,2]
So all we need to do is implement f. Suppose the predicate is called p. Then:
f x xs = if p x then x : xs else []
And now we can write
func p = foldr f [] where
f x xs = if p x then x : xs else []

Converting a foldl into fold1

I am using the following fold to get the final monotonically decreasing sequence of a list.
foldl (\acc x -> if x<=(last acc) then acc ++ [x] else [x]) [(-1)] a
So [9,5,3,6,2,1] would return [6,2,1]
However, with foldl I needed to supply a start for the fold namely [(-1)]. I was trying to turn into to a foldl1 to be able to handle any range of integers as well as any Ord a like so:
foldl1 (\acc x -> if x<=(last acc) then acc ++ [x] else [x]) a
But I get there error:
cannot construct infinite type: a ~ [a]
in the second argument of (<=) namely last acc
I was under the impression that foldl1 was basically :
foldl (function) [head a] a
But I guess this isn't so? How would you go about making this fold generic for any Ord type?
I was under the impression that foldl1 was basically :
foldl (function) [head a] a
No, foldl1 is basically:
foldl function (head a) (tail a)
So the initial element is not a list of head a, but head a.
How would you go about making this fold generic for any Ord type?
Well a quick fix is:
foldl (\acc x -> if x<=(last acc) then acc ++ [x] else [x]) [head a] (tail a)
But there are still two problems:
in case a is an empty list, this function will error (while you probably want to return the empty list); and
the code is not terribly efficient since both last and (++) run in O(n).
The first problem can easily be addressed by using pattern matching to prevent that scenario. But for the latter you better would for instance use a reverse approach. Like for instance:
f :: Ord t => [t] -> [t]
f [] = [] -- case when the empty list is given
f a = reverse $ foldl (\acc#(ac:_) x -> if x <= ac then (x:acc) else [x]) [head a] (tail a)
Furthermore personally I am not a huge fan of if-then-else in functional programming, you can for instance define a helper function like:
f :: Ord t => [t] -> [t]
f [] = [] -- case when the empty list is given
f a = reverse $ foldl g [head a] (tail a)
where g acc#(ac:_) x | x <= ac = (x:acc)
| otherwise = [x]
Now reverse runs in O(n) but this is done only once. Furthermore the (:) construction runs in O(1) so all the actions in g run in O(1) (well given the comparison of course works efficient, etc.) making the algorithm itself O(n).
For your sample input it gives:
*Main> f [9,5,3,6,2,1]
[6,2,1]
The type of foldl1 is:
Foldable t => (a -> a -> a) -> t a -> a
Your function argument,
\acc x -> if x<=(last acc) then acc ++ [x] else [x]
has type:
(Ord a) => [a] -> a -> [a]
When Haskell's typechecker tries typechecking your function, it'll try unifying the type a -> a -> a (the type of the first argument of foldl1) with the type [a] -> a -> [a] (the type of your function).
To unify these types would require unifying a with [a], which would lead to the infinite type a ~ [a] ~ [[a]] ~ [[[a]]]... and so on.
The reason this works while using foldl is that the type of foldl is:
Foldable t => (b -> a -> b) -> b -> t a -> b
So [a] gets unified with b and a gets unified with the other a, leading to no problem at all.
foldl1 is limited in that it can only take functions which deal with only one type, or, in other terms, the accumulator needs to be the same type as the input list (for instance, when folding a list of Ints, foldl1 can only return an Int, while foldl can use arbitrary accumulators. So you can't do this using foldl1).
With regards to making this generic for all Ord values, one possible solution is to make a new typeclass for values which state their own "least-bound" value, which would then be used by your function. You can't make this function as it is generic on all Ord values because not all Ord values have sequence least bounds you can use.
class LowerBounded a where
lowerBound :: a
instance LowerBounded Int where
lowerBound = -1
finalDecreasingSequence :: (Ord a, LowerBounded a) => [a] -> [a]
finalDecreasingSequence = foldl buildSequence lowerBound
where buildSequence acc x
| x <= (last acc) = acc ++ [x]
| otherwise = [x]
You might also want to read a bit about how Haskell does its type inference, as it helps a lot in figuring out errors like the one you got.

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

Haskell beginner query

Hi I have a query about a simple haskell definition. I have a definition but I don't fully understand it.
The function takes in a list of functions and an item and returns a list formed by applying that function.
applyAll = \fs -> \x -> map(\n -> n x) fs
Could somebody explain what n does and why is fs outside the map function?
The spacing is misleading you. It looks like map(\n -> n x) is a function call, but the parentheses here are for grouping, not function call. map takes two arguments; the full call is map (\n -> n x) fs, where (\n -> n x) is the first argument (a lambda expression) and fs is the second.
The lambda \n -> n x is a function that takes a function as an argument and returns the result of applying that function to x. n is the argument here. The type of \n -> n x is (a -> b) -> b (where a is the type of x). If you have learned about sections yet, the lambda is equivalent to the section ($ x). If you haven't, ignore that last sentence.
The function definition:
applyAll = \fs -> \x -> map(\n -> n x) fs
is the same as:
applyAll fs x = map(\n -> n x) fs
Now you might ask, "What are those ->s doing there if they are just arguments to my function applyAll. Haskell has no concept of multi-param functions. What you see as multiple arguments to a function is just many functions chained together each with a single argument. In the case of applyAll, it's just two functions chained together:
(applyAll fs) -> x = map (\n -> n x) fs
applyAll fs is one function chained to another argument identified as x to yield a list of values returned by map.
I could try this out in ghci:
Prelude> :t applyAll
applyAll :: [t -> b] -> t -> [b]
Prelude> :t applyAll xs
<interactive>:1:10: Not in scope: `xs'
Prelude> let xs = [1..5]
-- hah, BOOM! I told you haskell's strongly typed...
Prelude> :t applyAll xs
<interactive>:1:10:
Couldn't match expected type `t0 -> b0' with actual type `Integer'
Expected type: [t0 -> b0]
Actual type: [Integer]
In the first argument of `applyAll', namely `xs'
In the expression: applyAll xs
Prelude> let xs = [(1 +), (2 +), (3 *), (4 /)]
Prelude> :t xs
xs :: [Double -> Double]
Prelude> :t applyAll xs
applyAll xs :: Double -> [Double]
Prelude> :t applyAll
applyAll :: [t -> b] -> t -> [b]
Prelude> :t applyAll xs 3
applyAll xs 3 :: [Double]
Prelude> applyAll xs 3
[4.0,5.0,9.0,1.3333333333333333]
What's the type of map?
map :: (a -> b) -> [a] -> [b]
This tells me that map takes a function - let's call it f and a list of values to return another list of values. The function f is one that takes a value of type a returning another of type b. So map goes on applying f to each value in the list [a] to return another list filled with values of type b.
In your applyAll, the function f is \n -> n x. This is a lambda expression(you might call it an anonymous function) taking a value identified by n and applying x to it. This goes on for every item in the input list identified by [a] in the type definition until it runs out to yield another list identified by [b] in the type definition.
Here's a simple function definition:
f x = 2*x + 1
This creates a new function f, which takes one argument. You could use it later like this:
main = print (f 3)
...which would print 7. Sometimes, it is convenient to define a function without giving it a name. The syntax for that is \{- argument -} -> {- function body -}; for example, we could do an anonymous version of f above this way:
main = print ((\x -> 2*x + 1) 3)
Now, your definition of applyAll is just doing this several times. We could explicitly name everything in where clauses if we wanted:
applyAll = outerMost where
outerMost fs = mapApply where
mapApply x = map applyToX fs where
applyToX n = n x
...though I think you'll agree that the extra verbosity doesn't make things much more clear! A more natural (but less mechanical) translation away from anonymous functions would look like this:
applyAll fs x = map applyToX fs where
applyToX n = n x
and now hopefully this can very nearly read like English: to apply all the functions fs to a single value x, we map "the function that applies a single function (which we temporarily name n) to the value x" over the list of all functions.

Haskell - what is wrong with this function?

i am trying to compute the harmonic series with the function below. But there's a type error and not quite sure what it mean? another question, why [5..1] would gives an empty list?
sumHR = foldr (+) 0 (\x -> map (1/) [1..x])
error message:
*** Expression : foldr (+) 0 (\x -> map (1 /) (enumFromTo x 1))
*** Term : \x -> map (1 /) (enumFromTo x 1)
*** Type : b -> [b]
*** Does not match : [a]
The error is telling you that your code is not well-typed and thus doesn't make sense.
Your function:
sumHR = foldr (+) 0 (\x -> map (1/) [1..x])
Consider:
Prelude> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
So for this to be true, (+) is the first argument and the types must unify (a -> b -> b and Num a => a -> a -> a unify to Num a => a -> a -> a).
The second argument is given type variable b, which we already know must be Num a => a. This is fine, you have provided 0 as the second argument.
The third argument must agree with the type Num a => [a]. However, you have provided a second argument that is a function:
Prelude> :t (\x -> map (1/) [1..x])
(\x -> map (1/) [1..x]) :: (Enum b, Fractional b) => b -> [b]
Unless you can show the compiler how a type of (Enum b, Fractional b) => b -> [b] can be made the same as Num a => [a] then you are stuck.
You might have ment a function such as:
sumHR x = foldr (+) 0 (map (1/) [1..x])
Were you trying to write it point-free? If so, you need to use the composition operator . to compose foldr (+) 0 with (\x -> map (1/) [1..x]).
sumHR = foldr (+) 0 . (\x -> map (1/) [1..x])
or, point-fully:
sumHR x = foldr (+) 0 (map (1/) [1..x])
(By the way, for efficiency you'll want to use foldl' instead of foldr)
The previous answers have explained how to fix the function with the signature you apparently want; however this isn't really a good way to compute a sequence since for each element you request it will have to start from the beginning. A far more efficient, an in Haskell actually easier, approach is to calculate one lazy list that represents the entire sequence. So, you start with
map (1/) [1..]
(or, perhaps more readable, [ 1/i | i<-[1..] ]), then perform "each element of the result is the sum of all preceding elements in the given list". This is called a scan. Since that is always strict in one entire side of the list (rather than just two elements, like a fold) it needs to be done from the left. You can write
sumHR' :: Fractional x => [x]
sumHR' = scanl (+) 0 [ 1/i | i<-[1..] ]
or, equivalently since the infinite list is never empty,
sumHR' = scanl1 (+) [ 1/i | i<-[1..] ]

Resources