I am struggling to think of a way to utilize these functions for this beginner level coding class that I am taking to learn functional programming in Haskell. The functions I have to write are shown below, asum is supposed to turn a list of integers [a1,a2,..,an] into the alternating sum a1-a2+a3-a4+.… and I am not sure how to approach it with these functions. The xor function is supposed to that computes the XOR of a list of Booleans. I need some help to understand how to use these functions and it would greatly appreciated. I am also new to Haskell so any explanations would help. Thanks I have to use map foldr foldl.
asum :: (Num a) => [a] -> a
xor :: [Bool] -> Bool
I would say start by running the following, one by one, in GHCi:
:t foldr
:info foldr
:doc foldr
:t foldl
:info foldl
:doc foldl
:t map
:info map
:doc map
Or better, open hoogle.haskell.org and search each of the above mentioned functions and click on the first link.
But I agree that Haskell documentation are difficult to read, especially for beginners. I'm a beginner and I have a lot of difficulty reading and understanding them.
Here's a function that uses map and foldr to show how foldr works:
printFoldr xs = foldr (\x acc -> "(" ++ x ++ " + " ++ acc ++ " )") "0" $ map show xs
Now running watch this:
printFoldr [1..5]
-- outputs the following:
"(1 + (2 + (3 + (4 + (5 + 0 ) ) ) ) )"
This shows us how foldr is evaluated. Before going into how foldr is evaluated, let's look briefly at map.
map show [1..5]
-- outputs the following:
["1","2","3","4","5"]
This means that map takes 2 arguments. A list and a function that is applied to each element of the list. The result is a new list with the function applied to each element. Thus, applying show to each number outputs their string representation.
Back to foldr. foldr takes 3 arguments:
a function of type a -> b -> b
an initial value of type b
a list of type [a]
foldr takes each and every value of the provided list and applies this function to it. What is special is that map retains the output of the function over each iteration and passes it to the function as its second argument on the next run. Therefore it is convenient to write the function that is passed foldr as follows: (\el acc -> do something). Now on the next iteration of foldr, acc will hold the value of the previous run and el will be the current element from the list. BTW, acc stands for accumulator and el for element. This enables us to reduce elements of the provided list to something completely new.
As you can see in printFoldr, the initial value is just an empty string but it gradually adds the lists elements to it showing how it would have reduced the elements of the list to their sum.
Here's an idea:
a1-a2+a3-a4+...
=
a1-(a2-(a3-(a4-(...(an-0)...))))
This fits pretty well to the foldr pattern of recursion,
foldr f z [a1,a2,a3,a4,...,an]
=
a1`f`(a2`f`(a3`f`(a4`f`(...(an`f`z)...))))
So it can be coded by setting f = ... and z = ... and calling
asum :: (Num a) => [a] -> a
asum xs = foldr f z xs
where
f = (...)
z = (...)
You will need to complete this definition.
For the XOR of a list of Booleans, assuming it is to be True if one and only one of them is True, and False otherwise, we can imagine this sequence of transformations:
[ True, False, False, True, True, False, ...]
==>
[ t, f, f, t, t, f, ...]
where t and f are some specially chosen numbers. And then we can find the sum of this second list (not alternating sum, just a sum of a list of numbers) and check whether it is equal to ... some (other?) special number, let's call it n1:
xor :: [Bool] -> Bool
xor bools = (aNumber ... n1)
where
list1 = bools
list2 = fun1 transform list1
transform False = f
transform True = t
f = ...
t = ...
aNumber = sum list2
n1 = ...
fun1 = ...
sum listOfNums = ...
fun1 is the function which transforms each element of its argument list according to the given function, called transform above. It is one of the two functions left from the three you were given, considering we've already been using foldr.
sum is to be implemented by using the last function that's left.
FYI,
map foo [a1,a2,a3,...,an]
=
[foo a1, foo a2, foo a3, ..., foo an]
and
foldl f z [a1,a2,a3,...,an]
=
((((z`f`a1)`f`a2)`f`a3)...)`f`an
Related
I'm trying to learn Haskell by solving exercises and looking at others solutions when i'm stuck. Been having trouble understanding as functions get more complex.
-- Ex 5: given a list of lists, return the longest list. If there
-- are multiple lists of the same length, return the list that has
-- the smallest _first element_.
--
-- (If multiple lists have the same length and same first element,
-- you can return any one of them.)
--
-- Give the longest function a suitable type.
--
-- Examples:
-- longest [[1,2,3],[4,5],[6]] ==> [1,2,3]
-- longest ["bcd","def","ab"] ==> "bcd"
longest :: (Foldable t, Ord a) => t [a] -> [a]
longest xs = foldl1 comp xs
where
comp acc x | length acc > length x = acc
| length acc == length x = if head acc < head x then acc else x
| otherwise = x
So foldl1 works as follows - input: foldl1 (+) [1,2,3,4] output: 10. As I understand it, it takes a function applies it to a list and "folds" it. The thing I don't understand is that comp acc x compares two lists and outputs the larger length list.
The thing I don't understand is with longest xs = foldl1 comp xs. How are two lists provided to comp to compare and what is foldl1 "folding" and what is the start accumulator?
Here is another shorter example of another fold that I thought I understood.
foldl - input: foldl (\x y -> x + y) 0 [1,2,3] output: 6
It starts at 0 and adds each element from left one by one. How does foldl exactly apply the two variables in the anonymous function. For instance if the anonymous function was (\x y z-> x + y + z) it would fail which I don't yet understand why.
I think your current notion of what foldl1/foldl does is not quite accurate. As others already explained foldl1 f (x:xs) == foldl f x xs so the first value in the list is taken as an accumulator.
You say that foldl1 (+) list takes each value of the list "one by one" and computes the sum. I think this notion is misleaing: Actually you do always take two values, add them and get an intermediate result. And you repeat that over and over again with one of the values being the intermediate result of the last. I really like following illustration:
Source
If you start to think about these intermediate values, it will make more sense that you always get the largets one.
I think it is easiest to understand if you look at a symbolic example:
foldl k z [a, b, c] = k (k (k z a) b) c
foldl1 k [a, b, c] = k (k a b) c
As you can see foldl1 just starts with the first two arguments and then adds on the rest one by one using k to combine it with the accumulator.
And foldl starts by applying k to the initial accumulator z and the first element a and then adds on the rest one by one.
The k function only ever gets two arguments, so you cannot use a function with three arguments for that.
This question already has answers here:
How does foldr work?
(11 answers)
Closed 6 years ago.
So I came across the foldr function in Haskell which from what I pick up, you can use to calculate the product and sum of a list:
foldr f x xs
foldr (*) 1 [1..5] = 120
foldr (+) 0 [1..5] = 15
And adding numbers onto the x part would like, add on to the overall sum or multiply onto the final product
What does foldr actually do and why would anyone use it instead of the built in functions 'sum' or 'product' etc?
sum and product are themselves defined using fold (foldl, not foldr, but let's set aside that distinction for now), so in a sense you are using fold when using those functions. Likewise or, and, concat and many more are all defined using folds as well. So that's already one reason for folds to exist: many of the standard functions can be defined using them instead of having redundant code.
So when would you use folds directly? When doing something that there isn't already a specific function for, i.e. when you want to combine the elements of the list using something other than + or * (or ||, && or ++).
Say you have a list of single-digit numbers and you want to "concatenate" them into one number:
concatDigits = foldl (\acc d -> d + acc * 10) 0
Now concatDigits [1,2,3] gives you 123.
Or you've defined some datastructure and you want to convert lists to it:
fromList = foldr insert empty`
In fact that's how fromList is commonly defined for many data structures.
The Wikipedia entry has a good illustration of what foldr does to a list and how it differs from foldl.
The list [1,2,3] is generated by the cons operator (:) and the empty list [] by this expression tree:
:
/ \
1 :
/ \
2 :
/ \
3 []
foldr f z replaces the cons operator nodes with f and the empty list with z:
By contrast, foldl f z reorients the expression tree and repositions the zero element at the opposite end of the computation:
Some observations:
Note that foldr (:) [] leaves a list unchanged:
foldr (:) [] [1..10] == [1..10]
This makes sense since we are simply replacing the cons operator with itself and the empty list with the empty list and thus not changing anything.
If we replace the empty list with some other list we should be able to append two lists, e.g.:
foldr (:) [9,8,7] [1,2,3] == [1,2,3,9,8,7]
The cons operator may be thought of a way to add an element to a list:
(:) :: a -> [a] -> [a]
If we define f as:
f :: Int -> [Int] -> [Int]
f a as = [0] ++ [a] ++ as
then foldr f [] will prepend a 0 before each element of the input list:
foldr f [] [1,2,3] == [0,1,0,2,0,3]
Data.Set has a function insert whose signature is structually similar to that of (:):
insert :: Ord a => a -> Set a -> Set a
Indeed, we can convert a list to a Set using foldr
import qualified Data.Set as S
foldr S.insert S.empty [1,2,3]
Note how the empty list is replaced with the empty set - S.empty.
This is the idiomatic approach to building up data structures one element at a time - e.g. hash maps, tries, trees, etc.
This question already has answers here:
What does the : infix operator do in Haskell?
(4 answers)
Closed 8 years ago.
I've tried looking it up in hoogle and other various haskell dictionaries, but I can't find it. I was under the impression that it prepends, but I'm starting to see it in ways I haven't before and I've started second guessing myself.
For example, this is one of the questions that I don't understand:
(3 points) Fill in the blank with a pattern such that fun1 [(5,6),(7,8)] returns
5 and fun1 [(10,20),(30,40),(50,60)] returns 10:
and the answer is apparently:
((y,_):_)
fun1 _____________ = y
But I am so confused by this. I understand that the underscores mean that you don't really care about what the types of those are, but I don't understand what the (:) does in this answer.
While the other answers correctly explain what : is they don't quite answer the question - in the answer you have in your question : isn't used as a function, but as a constructor to pattern match on. fun (x:xs) = x means "if the argument is of the format (x:xs) give me the x". Pattern matching is used to "pull apart" complex types based on their constructors in Haskell.
In particular, since : is a list constructor you can pull apart lists with :
(conceptually list is defined as data [] a = [] | (:) a [a], although you're not gonna get this to compile because it's builtin syntax).
A non list example: We could define a datatype data F a b = A a | B b. This would create a type F that's parameterized with two types a and b and two constructors A and B with the types a -> F a b and b -> F a b respectively.
You could then write functions that use pattern matching to get at the contained values, like
isA (A _) = True -- this value was constructed with A, so it is an A
isA (B _) = False -- this value was constructed with B so it is not an A
or
getA (A a) = a -- this value was constructed with A so we can get an a out of it
getA (B _) = undefined -- ohps! We can't get an a back here cause we don't have one!
It is a List constructor function. It is used for prepending any value in front of the list.
ghci> 2 : [3,4]
[2,3,4]
It is just another Haskell function. You can also see it's type in ghci:
ghci> :t (:)
(:) :: a -> [a] -> [a]
Regarding your question, the answer is like this ((y,_):_) because it is being used in pattern matching. The first _ is the second element of the pair and the second _ pattern matches a list.
This may help you:
ghci> (5,6):[(7,8)]
[(5,6),(7,8)]
: is the list constructor of type a -> [a] -> [a]. It is usually used infix. but you can use it as prefix if you surround it with parentheses as you did. Just like any infix operation. (E.g. (+) 4 5 == 4 + 5)
So (:) a as is the same as a:as
Every constructor in Haskell can be also used do deconstruct a value of the type if constructs in a pattern match:
f x:xs = xs
would for example define a function that takes a non empty list and returns the tail. It would fail on an empty list because the empty list is constructed by the nullary constructor []. You could make f total by adding that second constructor to the match.
f [] = []
I guess your confusion comes from the fact that in haskell there is syntactic sugar that allows you to write lists in a more convenient way. Instead of (1:(2:(3:[]))) you can write [1,2,3] which is expanded into the former by the compiler.
In addition to the answers of what (:) function does, please, bear in mind that in the context of your question : is used as a deconstructor.
It is better to view (:) as a constructor. Then, just like any other data constructor, it can be used to introspect the contents of the value. Examples are:
f (Just x) = x -- extracts the value wrapped into Maybe a
f (x:_) = x -- extracts the value wrapped into a list, [a]
f ((x,_):_) = x -- extracts the value wrapped into a tuple in the list of tuples
In all these cases Just, : and (,) are constructors. The same syntax can be used to construct or deconstruct the values - depending on the context of the expression. Compare:
f x = Just x -- wraps x into Maybe a
f x xs = x:xs -- wraps x into a list, [a]
f x y z = (x,y):z -- wraps x into a tuple in the list of tuples
To understand what fun1 does, let's first look at another function:
f (x:xs) = x
If you pass this function a list such as [5,12,33], it will match x to 5, and xs to [12,33]. The function just returns x, i.e. the first element. So this function is basically the same as head. Since we don't actually use the value xs, we can rewrite the function as:
f (x:_) = x
Now let's look at fun1, but a slightly modified version.
fun1 ((y,z):xs) = y
If we pass this function the list [(5,6),(7,8)], it will match (y,z) to the pair (5,6) and xs to [(7,8)]. So now y is 5, and that's the value we return. Again, since we don't use z or xs, we can write the function as:
fun1 ((y,_):_) = y
I am new to Haskell and I have the following problem. I have to create a list of numbers [f1, f2, f3...] where fi x = x ^ i. Then I have to create a function that applies the fi to a list of numbers. For example if I have a list lis = [4,5,6,7..] the output would be [4^1, 5^2,6^3, 7^4...]. This is what I have written so far :
powers x= [x^y |y<-[1,2,3,4]]
list = [1,2,3,4]
match :: (x -> xs) -> [x] -> [xs]
match f [] = []
match f (x:xs) = (f x) : ( match f xs )
So if I put the list = [1,2,3] the output is [1,1,1,1][2,4,8,16],[3,9,27,81] instead of [1,4,27]
Can you please tell me what is wrong and point me to the right direction?
The first issue is that powers is of type Int -> [Int]. What you really want, I think, is something of type [Int -> Int] -- a list of Int -> Int functions instead of a function that takes an Int and returns a list of Int. If you define powers like so:
powers = [(^y) | y <- [1..4]]
you can use zipWith to apply each power to its corresponding element in the list, like so:
zipWith ($) powers [1,2,3] -- returns [1,4,27]
The ($) applies its left (first) argument to its right (second) argument.
Note that using powers as defined here will limit the length of the returned list to 4. If you want to be able to use arbitrary length lists, you want to make powers an infinite list, like so:
powers = [(^y) | y <- [1..]]
Of course, as dave4420 points out, a simpler technique is to simply use
zipWith (^) [1,2,3] [1..] -- returns [1,4,27]
Your match is the standard function map by another name. You need to use zipWith instead (which you can think of as mapping over two lists side-by-side).
Is this homework?
You are currently creating a list for every input value.
What you need to do is recursively compute the appropriate
power for each input value, like this:
match f [] = []
match f (x:xs) y = (f x y) : (match f xs y+1)
Then, you can call this as match pow [1, 2, 3] 1.
This is equivalent to using zipWith and providing the desired function (pow), your input list ([1, 2, 3]) and the exponent list (a lazy one to infinity list) as arguments.
I need to define a function 'Compose' which takes a list 'L' which is a list of functions. When I specify a parameter that will suit all the functions in the list, the last function evaluates itself using this param. The result is then passed to the second last function and so on until we get to the first item (function) in the list and we get the final result.
E.g.
Compose ( ( fn N -> N + 1 ) ^ ( fn N -> 2 * N ) ^ # ) 3 .
give the answer 7.
I have to write this in a functional programming language called SAL (simple applicative language) devised by a lecturer in my college (hence funny syntax above ( ^ seperates list items and # marks end of list)).
If any solutions could be written in pseudo-code bearing in mind I can't use loops, variables etc. that would be much appreciated. Apparently the solution is a one-line answer. I imagine it involves recursion (99% of our task functions do!).
Also I don't understand Haskell (guess I'll have to learn!) so psuedo code or even plain English would be great. –
Thanks a bunch.
If the solution is a one-line answer, it could be something involving a fold:
compose :: [a -> a] -> a -> a
compose fs v = foldl (flip (.)) id fs $ v
http://haskell.org/haskellwiki/Compose
You can also implement it as a right fold, which works the way you want:
compose = foldr (.) id
*Main> let compose = foldr (.) id
*Main> compose [\x -> x+1, \x -> 2 * x, id] 3
7
in haskell:
compose :: a -> [a -> a] -> a
compose a (x:xs) = x (compose a xs)
compose a [] = a
Dan kind of gives it away, but here's a hint on how to do it yourself. You can recurse over numbers:
0! = 1
n! = (n-1)! * n
You can also recurse over structure. A list, for example, has a recursive structure, broken down into two cases: an empty list, and an item followed by the rest of the list. In no particular language:
List := Item x List
| Nil
Item marks the head of the list, x is the value stored in the head, and List is the tail. In this grammar, your list would be written:
Item ( fn N -> N + 1 ) Item ( fn N -> 2 * N ) Nil
The rule for a list in the syntax your professor invented could be written recursively as:
List := x ^ List
| #
A function on a list must recurse over this structure, which means it handles each of the two cases:
sum l:List = Nil -> 0
| Item x xs:List = x + sum xs
The recursion, specifically, is the term sum l:List = x + sum xs. Writing this function using the professor's syntax left as an exercise.
In your problem, your metafunction takes a list of functions and must return a function. Consider each case, the empty list and an item (the head) followed by a list (the tail). In the latter case, you can recursively use your function to get a function from the tail, then combine that somehow with the head to return a function. That's the gist, at any rate.
The same using monoids, point-free
import Data.Monoid
compose :: [a -> a] -> a -> a
compose = appEndo . mconcat . map Endo
Or somewhat more generally:
import Data.Monoid
compose :: (Functor t, Foldable t) => t (a -> a) -> a -> a
compose = appEndo . foldl1 (<>) . fmap Endo
Here's what I used:
compose :: [a -> a] -> a -> a
compose list startingvalue = foldl (\x f -> f x) startingvalue list