I'm playing around with Haskell since I'm learning the language, and I just found something I don't understand and I can't find an explanation. If I try to run this code:
map (`div` 0) [1,2,3,4]
I get a divide by 0 exception, which is expected.
But if I run this code:
length (map (`div` 0) [1,2,3,4])
I get 4!
I'd like to know why I don't get the divide by 0 exception when I do the mapping inside the length function!
The map and length functions can be defined this way:
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
length :: [a] -> Int
length [] = 0
length (_:xs) = 1 + length xs
Now, let's work out by hand why your second example works the way it does. It goes like this:
length (map (`div` 0) (1:2:3:4:[]))
= length (1 `div` 0 : map (`div` 0) (2:3:4:[])) -- second map equation
= 1 + (length (map (`div` 0) (2:3:4:[]))) -- second length equation
= 1 + (length (2 `div` 0 : map (`div` 0) (3:4:[]))) -- second map equation
.
.
.
= 1 + (1 + (1 + (1 + length (map (`div` 0) []))))) -- second length equation
= 1 + (1 + (1 + (1 + length [])))) -- first map equation
= 1 + (1 + (1 + (1 + 0)))) -- first length equation
= 4 -- arithmetic
What's the trick here? In Haskell the process of evaluating an expression is called forcing it. Forcing an expression performs the minimum work necessary in order to figure out the outermost data constructor of the result. As part of this, subexpressions will be forced only as necessary to achieve the goal.
So in this example, the outermost expression we're forcing is an application of the length function. The definition of length has two cases, one which uses the [] list constructor and the other which uses the (:) constructor, so to apply length we need to figure out which of these two cases to apply to the argument. Since the argument doesn't have either constructor in its outermost position, we have to force it to find out. That's what happens in the step between the first and the second line of the derivation above; we force the map subexpression by looking at its arguments and choosing the second map equation.
But after that point, we have all the information we need to determine which of the two equations for length applies, so we go by the "outermost first" rule and apply the appropriate length equation. In this case, this discards the subexpression that contains the division by zero, which means that subexpression will never be forced, and the error will never be triggered.
In your first example, however, when you type the expression into GHCI, you're implicitly asking the interpreter to print its result. This requires it to force the spine of the list to access its elements, and force the elements themselves to print them. So the division by zero error happens when you force the first element of the list.
EDIT: Let me point out one nuance you may have not noticed. When we try your first example in GHCI, this is the result of the session:
*Main> map (`div` 0) [1,2,3,4]
[*** Exception: divide by zero
See that lonely opening square bracket at the beginning of the second line? That's the opening bracket for the list that was being printed, before the divide by zero error happened. Likewise, notice what happens in this example:
*Main> map (20 `div`) [1,2,0,4]
[20,10,*** Exception: divide by zero
The first two elements of the result list, and even the comma separating the second element from the third, print successfully because Haskell doesn't attempt to compute the third list element until it needs to be printed.
If you type the map expression into the interpreter, it will evaluate it and then print the resulting list. In order to do that all elements of the resulting list need to be evaluated because they will be part of the string that is displayed.
However when the interpreter evaluates the length expression, it only needs to look at the structure of the resulting list. It does not have to look at the actual elements inside the list. So since Haskell, being a lazy language, only evaluates what it has to, that means that the elements will not be evaluated and thus no exception is thrown.
This is some good old Haskell lazy evaluation! If Haskell doesn't have to compute something, it wont. In this case, you are calling map on a list of length 4. As far as Haskell is concerned, applying map to any list will return a list of the same size, regardless of what operation you are applying. Therefore, Haskell simply tells you the length is 4, without actually dividing anything by 0.
Related
I want to write a function which takes a list of integers and returns a list where every element is negative.
negate :: [Int] -> [Int]
negate xs = foldl (\x xs -> (abs x * (-1)) : xs) [] xs
This function negate all the array objects but also reverse the locations of all variables in the array. What make this function reverse the locations?
foldl does! foldl is a left fold, so it works on your list by starting with its initial state (which you provide as []) and the leftmost element of the list, and calls your function which prepends the negation of that element to the state. Then it takes the next leftmost element and does the same thing. But you're prepending each time, which means that the first element of your input ends up corresponding to the last element of the output, because it was the first to get prepended.
You might want foldr for this, which is a fold that starts with the rightmost element. Alternatively, using map would be a simpler approach for this particular problem.
Sample code:
makeAllNegative = map (negate . abs)
I want to calculate the "e" constant using Haskell's (Prelude) built-in until function. I want to do something like this:
enumber = until (>2.7) iter (1 0)
iter x k = x + (1/(fact (k + 1)))
fact k = foldr (*) 1 [1..k]
When I try to run this code, I get this error:
Occurs check: cannot construct the infinite type: a ~ a -> a
Expected type: (a -> a) -> a -> a
Actual type: a -> a -> a
Relevant bindings include enumber :: a -> a (bound at Lab2.hs:65:1)
In the second argument of ‘until’, namely ‘iter’
In the expression: until (> 2.7) iter (1 0)
By "e" I mean e = 2.71828..
The concrete mistake that causes this error is the notation (1 0). This doesn't make any sense in Haskell, it is parsed such that 1 is a function which is applied to 0, and the result then used. You apparently mean to pass both 1 and 0 as (initial) arguments. That's what we have tuples for, written (1,0).
Now, before trying to make anything definitions, we should make clear what types we need and write them out. Always start with your type signatures, they guide you a lot to you the actual definitions should look!
enumber :: Double -- could also be a polymorphic number type, but let's keep it simple.
type Index = Double -- this should, perhaps, actually be an integer, but again for simlicity use only `Double`
fact :: Index -> Double
now, if you want to do something like enumber = until (>2.7) iter (1,0), then iter would need to both add up the series expansion, and increment the k index (until knows nothing about indices), i.e. something like
iter :: (Double, Index) -> (Double, Index)
But right now your iter has a signature more like
iter :: Double -> Index -> Double
i.e. it does not do the index-incrementing. Also, it's curried, i.e. doesn't accept the arguments as a tuple.
Let's try to work with a tuple signature:
iter :: (Double, Index) -> (Double, Index)
iter (x,k) = ( x + 1/(fact (k + 1)), k+1 )
If you want to use this with until, you have the problem that you're always working with tuples, not just with the accumulated results. You need to throw away the index, both in the termination condition and in the final result: this can easily be done with the fst function
enumber = fst $ until ((>2.7) . fst) iter (1,0)
Now, while this version of the code will type-check, it's neither elegant nor efficient nor accurate (being greater than 2.7 is hardly a meaningful condition here...). As chi remarks, a good way of summing up stuff is the scanl function.
Apart from avoiding to manually increment and pass around an index, you should also avoid calculating the entire factorial over and over again. Doing that is a pretty general code smell (there's a reason fact isn't defined in the standard libraries)
recipFacts :: [Double] -- Infinite list of reciprocal factorials, starting from 1/0!
recipFacts = go 1
where go k = 1 : map (/k) (go (k+1))
Incidentally, this can also be written as a scan: scanl (/) 1 [1..] (courtesy of Will Ness).
Next we can use scanl to calculate the partial sums, and use some termination condition. However, because the series converges so quickly, there's actually a hack that works fine and is even simpler:
enumber :: Double
enumber = sum $ takeWhile (>0) recipFacts
-- result: 2.7182818284590455
Here I've used the fact that the fast-growing factorial quickly causes the floating-point reciprocals to underflow to zero.
Of course, really there's not a need to sum anything up yourself at all here: the most to-the-point definition is
enumber = exp 1
and nothing else.
enumber = until (>2.7) iter (1 0)
-- ^^^^^
Above you are applying "function" 1 to argument 0. This can't work.
You may want to use a pair instead (1, 0). In that case, not that iter must be changed to accept and return a pair. Also, the predicate >2.7 must be adapted to pairs.
If you don't want to use pairs, you need a different approach. Look up the scanl function, which you can use to compute partial sums. Then, you can use dropWhile to discard partial sums until some good-enough predicate is satisfied.
An example: the first ten partial sums of n^2.
> take 10 $ scanl (+) 0 [ n^2 | n<-[1..] ]
[0,1,5,14,30,55,91,140,204,285]
Note that this approach works only if you compute all the list elements independently. If you want to reuse some computed value from one element to another, you need something else. E.g.
> take 10 $ snd $ mapAccumL (\(s,p) x -> ((s+p,p*2),s+p)) (0,1) [1..]
[1,3,7,15,31,63,127,255,511,1023]
Dissected:
mapAccumL (\(s,p) x -> ((s+p,p*2),s+p)) (0,1) [1..]
a b c d e
s previous sum
p previous power of two
x current element of [1..]
a next sum
b next power of two
c element in the generated list
d first sum
e first power of two
Still, I am not a big fan of mapAccumL. Using iterate and pairs looks nicer.
I am trying to understand laziness. Because 0 multiplied with any number is 0, shouldn't product [0..] evaluate to 0? I tried also foldl (*) 1 [0..], and to define my own product as
myProduct 0 _ = 0
myProduct _ 0 = 0
myProduct a b = a*b
Why doesn't the fold stop as soon as a 0 is found?
Because the multiply operator doesn't know it's getting chained, and the fold function doesn't know the multiply operator's particular behaviour for any argument. With that combination, it needs to exhaust the list to finish the fold. In fact, for this reason foldl doesn't work at all on infinite lists. foldr does, because it can expand the function from the head of the list.
foldl (*) 1 [0..] -> (((..(((1*0)*1)*2)*3....)*inf
The outermost multiplication in the foldl case can never be found, because the list is infinite. It therefore cannot follow the chain to conclude the result is zero. It can, and does, calculate the product along the list, and that product happens to stay zero, but it will not terminate. If you use scanl instead you can see these intermediate products.
foldr (*) 1 [0..] -> 0*(1*(2*(3*((...((inf*1)))...)))
The outermost multiplication in the foldr case is found immediately, because the rest of the list is in fact left as a lazy thunk. It only runs one step:
foldr (*) 1 [0..] -> 0*(foldr (*) 1 [1..])
So because your custom multiplication operator myProduct is not strict in the second argument if the first argument is zero, foldr myProduct 1 [0..] can terminate.
As a side note, the prelude product function is restricted to finite lists (and may be implemented with foldl). Even if it used foldr, it probably would not shortcut because the standard multiply operator is strict; doing otherwise would be computationally expensive in the common case where the products are neither zero nor chained.
-- sum and product compute the sum or product of a finite list of numbers.
sum, product :: (Num a) => [a] -> a
sum = foldl (+) 0
product = foldl (*) 1
In addition, there's a reason it does not use foldr; as we could see in the expansions and scanl function, the left folds can compute as they consume the list. The right fold, if the operator does not shortcut, needs to build an expression as large as the list itself to even begin computation. This difference is because it's the innermost expression that starts the computation in the strict case, but the outermost expression that produces the result, allowing the lazy case. Lazy vs. non-strict in the Haskell wiki might explain better than I can, and even mentions that pattern matching, which you used to describe the shortcut in myProduct, can be strict.
If you switch the first two lines:
myProduct _ 0 = 0
myProduct 0 _ = 0
myProduct a b = a*b
the second argument will always be evaluated before the first one and the infinite foldr won't work anymore.
Since its impossible to define a myProduct that works lazily for both arguments (not evaluating the second if the first is 0 and not evaluating the first if the second is 0) maybe we are better off with having * always evaluate both its arguments.
You can have it thusly:
myproduct xs = foldr op id xs 1
where
op x r acc = if x==0 then 0 else acc `seq` r (acc*x)
This is a right fold that multiplies the numbers from the left, operating in constant space, and stops as soon as a 0 is encountered.
I need to make a function "powers" that takes a number n and returns the infinite list of that number to the power of every number e.g.
powers 2 = 2,4,8,16,32......
I need to do this using very specific subset of the language where my only available built in functions are: div, mod, even, odd, head, tail, not, null, length, reverse, elem, map, filter, foldr, sum, product, take, drop, takewhile, dropWhile, zipWith and from.
the subset also has no ^ operator.
there are some further important constraints:
the code must not exceed 1 line of more than 80 characters
no "helper functions" allowed, i.e i cannot write another function to use within this definition.
So far my thinking is along these lines:
powers = \n -> map (\x -> "some function to get n to the power of x") (from 1)
but i cant figure out how to get the function to do this without a helper function.
for example if i was to use a function inflist that returned an infinite list of the number x then i could just do the following.
powers = \n -> map (\x -> product(take x (inflist n))) (from 1)
but i cant do this or anything like it because i couldn't use that function.
Sorry if the notation is a different to normal haskell, its a very strict core haskell subset that uses this notation.
This is a recursion question.
powers n = n : map (* n) (powers n)
(Are you allowed to use :?)
This was fun and funner when the insight came.
Generate successively longer repetitions of 2 in lists with
[ [ 2 | y <- [1..x]] | x <- [1..]]
Then take the product of each list.
map product [ [ 2 | y <- [1..x]] | x <- [1..]]
Be sure to use take x before an invocation
I struggled with a mod and multiple mod functions to limit lists.
If iterate were allowed.
take 24 $ iterate (2*) 2
would generate the list.
Edit 4/4/2018
An infinite recursive function, may be what you are looking for to fill out your function. It might be:
pow l = l ++ pow [(last l * 2)]
To produce a list it is absolutely necessary to assemble a list and it is necessary to use the last element of the list to calculate the next in sequence. This must also be run with take. Also the command following starts the list with 1. It can be started with any number such as 64 or 63. I tried passing the last value as a parameter but then the function would not generate a list. There is a choice, use ':' instead of '++' but it will produce each element in a list. To produce a list of values instead of a list of lists used 'concat $ ' before 'take' to clean it up.
take 10 $ pow [1]
So, I'm new here, and I would like to ask 2 questions about some code:
Duplicate each element in list by n times. For example, duplicate [1,2,3] should give [1,2,2,3,3,3]
duplicate1 xs = x*x ++ duplicate1 xs
What is wrong in here?
Take positive numbers from list and find the minimum positive subtraction. For example, [-2,-1,0,1,3] should give 1 because (1-0) is the lowest difference above 0.
For your first part, there are a few issues: you forgot the pattern in the first argument, you are trying to square the first element rather than replicate it, and there is no second case to end your recursion (it will crash). To help, here is a type signature:
replicate :: Int -> a -> [a]
For your second part, if it has been covered in your course, you could try a list comprehension to get all differences of the numbers, and then you can apply the minimum function. If you don't know list comprehensions, you can do something similar with concatMap.
Don't forget that you can check functions on http://www.haskell.org/hoogle/ (Hoogle) or similar search engines.
Tell me if you need a more thorough answer.
To your first question:
Use pattern matching. You can write something like duplicate (x:xs). This will deconstruct the first cell of the parameter list. If the list is empty, the next pattern is tried:
duplicate (x:xs) = ... -- list is not empty
duplicate [] = ... -- list is empty
the function replicate n x creates a list, that contains n items x. For instance replicate 3 'a' yields `['a','a','a'].
Use recursion. To understand, how recursion works, it is important to understand the concept of recursion first ;)
1)
dupe :: [Int] -> [Int]
dupe l = concat [replicate i i | i<-l]
Theres a few problems with yours, one being that you are squaring each term, not creating a new list. In addition, your pattern matching is off and you would create am infinite recursion. Note how you recurse on the exact same list as was input. I think you mean something along the lines of duplicate1 (x:xs) = (replicate x x) ++ duplicate1 xs and that would be fine, so long as you write a proper base case as well.
2)
This is pretty straight forward from your problem description, but probably not too efficient. First filters out negatives, thewn checks out all subtractions with non-negative results. Answer is the minumum of these
p2 l = let l2 = filter (\x -> x >= 0) l
in minimum [i-j | i<-l2, j<-l2, i >= j]
Problem here is that it will allow a number to be checkeed against itself, whichwiull lend to answers of always zero. Any ideas? I'd like to leave it to you, commenter has a point abou t spoon-feeding.
1) You can use the fact that list is a monad:
dup = (=<<) (\x -> replicate x x)
Or in do-notation:
dup xs = do x <- xs; replicate x x; return x
2) For getting only the positive numbers from a list, you can use filter:
filter (>= 0) [1,-1,0,-5,3]
-- [1,0,3]
To get all possible "pairings" you can use either monads or applicative functors:
import Control.Applicative
(,) <$> [1,2,3] <*> [1,2,3]
[(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)]
Of course instead of creating pairs you can generate directly differences when replacing (,) by (-). Now you need to filter again, discarding all zero or negative differences. Then you only need to find the minimum of the list, but I think you can guess the name of that function.
Here, this should do the trick:
dup [] = []
dup (x:xs) = (replicate x x) ++ (dup xs)
We define dup recursively: for empty list it is just an empty list, for a non empty list, it is a list in which the first x elements are equal to x (the head of the initial list), and the rest is the list generated by recursively applying the dup function. It is easy to prove the correctness of this solution by induction (do it as an exercise).
Now, lets analyze your initial solution:
duplicate1 xs = x*x ++ duplicate1 xs
The first mistake: you did not define the list pattern properly. According to your definition, the function has just one argument - xs. To achieve the desired effect, you should use the correct pattern for matching the list's head and tail (x:xs, see my previous example). Read up on pattern matching.
But that's not all. Second mistake: x*x is actually x squared, not a list of two values. Which brings us to the third mistake: ++ expects both of its operands to be lists of values of the same type. While in your code, you're trying to apply ++ to two values of types Int and [Int].
As for the second task, the solution has already been given.
HTH