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.
Related
I want to see how long a list is, but without using the function length. I wrote this program and it does not work. Maybe you can tell me why? Thanks!
let y = 0
main = do
list (x:xs) = list (xs)
y++
list :: [Integer] -> Integer
list [] = y
Your program looks quite "imperative": you define a variable y, and then somehow write a do, that calls (?) the list function (?) that automagically seems to "return y" and then you want to increment y.
That's not how Haskell (and most functional and declarative) languages work:
in a declarative language, you define a variable only once, after the value is set, there is usually no way to alter its value,
in Haskell a do usually is used for monads, whereas the length is a pure function,
the let is a syntax construction to define a variable within the scope of an expression,
...
In order to program Haskell (or any functional language), you need to "think functional": think how you would solve the problem in a mathematical way using only functions.
In mathematics, you would say that the empty list [] clearly has length 0. Furthermore in case the list is not empty, there is a first element (the "head") and remaining elements (the "tail"). In that case the result is one plus the length of the tail. We can convert that in a mathematical expression, like:
Now we can easily translate that function into the following Haskell code:
ownLength :: [a] -> Int
ownLength [] = 0
ownLength (_:xs) = 1 + ownLength xs
Now in Haskell, one usually also uses accumulators in order to perform tail recursion: you pass a parameter through the recursive calls and each time you update the variable. When you reach the end of your recursion, you return - sometimes after some post-processing - the accumulator.
In this case the accumulator would be the so far seen length, so you could write:
ownLength :: [a] -> Int
ownLength = ownLength' 0
where ownLength' a [] = a
ownLength' a (_:xs) = ownLength' (a+1) xs
It looks you still think in an imperative way (not the functional way). For example:
you try to change the value of a "variable" (i.e. y++)
you try to use "global variable" (i.e. y) in the body of the list function
Here is the possible solution to your problem:
main = print $ my_length [1..10]
my_length :: [Integer] -> Integer
my_length [] = 0
my_length (_:xs) = 1 + my_length xs
You can also run this code here: http://ideone.com/mjUwL9.
Please also note that there is no need to require that your list consists of Integer values. In fact, you can create much more "agnostic" version of your function by using the following declaration:
my_length :: [a] -> Integer
Implementation of this function doesn't rely on the type of items from the list, thus you can use it for a list of any type. In contrast, you couldn't be that much liberal for, for example, my_sum function (a potential function that calculates the sum of elements from the given list). In this situation, you should define that your list consists of some numerical type items.
At the end, I'd like to suggest you a fantastic book about Haskell programming: http://learnyouahaskell.com/chapters.
Other answers have already beautifully explained the proper functional approach. It looks like an overkill but here is another way of implementing the length function by using only available higher order functions.
my_length :: [a] -> Integer
my_length = foldr (flip $ const . (+1)) 0
I've found this solution in Learn you a haskell.
length' xs = sum [1 | _ <- xs]
It replaces every element of the list with 1 and sums it up.
Probably the simplest way is to convert all elements to 1 and then to sum the new elements:
sum . map (const 1)
For added speed:
foldl' (+) 0 . map (const 1)
I tried to implement a function that takes a limit and a string, parses the string and tests if the parsed number exceeds the limit. The function works well only for strings without 0s in it, like "123". However, it could not parse strings correctly like "100", whose result is 1.
What caused this problem?
Below is the code.
reachBounded :: Int -> String -> Maybe Int
reachBounded limit str = case str of
"" -> Nothing
"0" -> Just 0
_ -> foldr (\digit s -> do
sum <- s
let n = sum * 10 + digitToInt digit
guard (isDigit digit)
guard (n <= limit)
return n)
(Just 0) str
Moreover, is there any way to debug this code like we normally do in imperative languages? I found ghci debugger only able to print the type, not the value.
This is a very imperative way of solving the problem, and if you keep thinking like that you're going to have difficulties moving forward.
Here's how you might want to re-think the problem:
Replace "I have a list of characters, but I want digits, I'll iterate and replace them one by one" with "I have a list of characters but I want digits, I'll just replace them all at once" (I'm going to assume you want to actually parse the string yourself fully manually rather than just using read or some kind of parsing tool)
So far we have:
reachBounded limit str = ... map digitToInt str
Next, you want to turn these digits into a number. Replace "I want to iterate through this list increment a sum" with "I need to know the place value of each digit". We can do this by reversing the digits and multiplying them pairwise with the list [1,10,100,1000...]. We can produce the place value list by mapping (10^) over the list of positive integers, or declaring that each element is 10 times the previous, starting with 1. Let's use the latter:
reachBounded limit str = ... zipWith (*) (iterate (*10) 1) $ reverse $ map digitToInt str
And we want the sum of these place values:
reachBounded limit str = ... where
val = sum $ zipWith (*) (iterate (*10) 1) $ reverse $ map digitToInt str
Lastly, we must check if it's within the bound given:
reachBounded limit str = val <$ guard (val < limit) where
val = sum $ zipWith (*) (iterate (*10) 1) $ reverse $ map digitToInt str
In this case a <$ b will replace the contents of b with a if b is Just something, and leave it alone if b is Nothing.
In terms of debugging, it is now trivial, as it is not some process we need to interrupt, but a series of values that we manipulate to get the desired result. You cannot run part of your process on each step and get a sensible answer, but here we can look at the result produced by any of these stages and see if we are on track.
There isn't a toMaybe :: (a -> Bool) -> a -> Maybe a function. I'm not sure why, but with one and using read, the solution is merely:
bounded l = toMaybe (<l) . read
Or using the Safe library...
bounded l = toMaybe (<l) <=< readMay
Which will not throw exceptions if you don't input a string that actually represents a number.
Now, let's say you really do want to write your algorithm iteratively, maybe you need to for performance or it's just one of those algorithms that doesn't readily admit a declarative implementation (there aren't many of those, though). It's still going to be cleaner to use values instead of exceptions, but you need to stop and look at it sometimes.. so what do you do?
Let's write our own iterator function:
data Iter a b c = Next a | Final b | Error c
iterateE :: (a -> Iter a b c) -> a -> ([a], Either c b)
iterateE f = go where
go x = case f x of
Next a -> let (list, final) = go a in (x:list, final)
Final b -> ([x], Right b)
Error c -> ([x], Left c)
This more directly encapsulates stopping the fold early and tracking the intermediate results - even though you can also just stop folds early and track the intermediate results - this is a simpler way to think about it for now. This will provide you with a complete list of all intermediate states and either a result or error that your iterator function can choose to terminate with.
Transforming your solution into this format...
reachBounded limit str = iterateE iter (Just 0,str) where
iter (n, []) = Final n
iter (n, (s:str)) = Next (do
sum <- s
let n = sum * 10 + digitToInt digit
guard (isDigit digit)
guard (n <= limit)
return n, str)
... we don't don't announce any error in this code, but this will let us see what's happened at each step, and also doesn't have a direction in the fold, so you can't get it backwards between left and right.
I'm playing with Haskell for first time.
I've created function that returns first precise enough result. It works as expected, but I'm using generator for this. How can I replace generator in this task?
integrateWithPrecision precision =
(take 1 $ preciseIntegrals precision) !! 0
preciseIntegrals :: Double -> [Double]
preciseIntegrals precision =
[
integrate (2 ^ power) pi | power <- [0..],
enoughPowerForPrecision power precision
]
You can use the beautiful until function. Here it is:
-- | #'until' p f# yields the result of applying #f# until #p# holds.
until :: (a -> Bool) -> (a -> a) -> a -> a
until p f x | p x = x
| otherwise = until p f (f x)
So, you can write your function like this:
integrateWithPrecision precision = integrate (2 ^ pow) pi
where
pow = until done succ 0
done pow = enoughPowerForPrecision pow precision
In your case, you do all the iteration and then compute a result just once. But until is useful even when you need to compute a result at each step - just use an (iter, result) tuple and then just extract the result at the end with snd.
It seems like you want to check higher and higher powers until you get one that satisfies a requirement. This is what you could do: First you define a function to get enough power, and then you integrate using that.
find gets the first element of a list that satisfies a condition – like being enough of a power! Then we need a fromJust to get the actual value from that. Please note that almost always, fromJust is a terrible idea to have in your code. However, in this case the list is infinite, so we will have troubles with infinite loops long before fromJust is able to crash the program.
enoughPower :: Double -> Int
enoughPower precision =
fromJust $ find (flip enoughPowerForPrecision precision) [0..]
preciseIntegrals :: Double -> Double
preciseIntegrals precision = integrate (2^(enoughPower precision)) pi
The function
\xs -> take 1 xs !! 0
is called head
head [] = error "Cannot take head of empty list"
head (x:xs) = x
Its use is somewhat unsafe, as shown it can throw an error if you pass it an empty list, but in this case since you can be certain your list is non-empty it's fine.
Also, we tend not to call these "generators" in Haskell as they're not a special form but are instead a simple consequence of lazy evaluation. In this case, preciseIntegrals is called a "list comprehension" and [0..] is nothing more than a lazily generated list.
The assignment is to define function decimal :: [Int] -> Int in which a list of positive ints is to give the decimal number so that the list [1,4,3,1,9] is to return the Integer 14319. I am to use the fold function.
I don't really have good idea to start here, so I just need a push in the right direction, but I was thinking about the Horner-scheme. Thanks!
In the fold, you start from the left and move towards the right. As you consume the next element from the list, you multiply what you already had by 10 and add the new element to that.
So if you seed the foldl with 0, and had [1,2,3], your function would multiply current (0) by 10 (also 0), then add 1. Moving on, multiply current (1) by 10 (to get 10) and add 2 (12). Then finally for 3, 12 * 10 = 120, 120 + 3 = 123.
That should be pretty easy to code up :)
Maybe this equation would guide you.
Since this is a homework, let's stop at the suggestion that you expand this expression for some list, and try to extract a recurrent relationship:
x_0*10^n+x_1*10^(n-1)+...+x_n*10^0 = (((x_0*10+x_1)*10+x_2)...)*10+x_n
If you compare this to folds, you will see one fold matches this pattern for a particular function of two arguments.
This is my variant
import Data.List
decimal :: [Int] -> Int
decimal xs = foldl' (\sum (pos,x) -> (sum + x*(10^(l-pos)))) 0 $ zip [1..] xs where
l = length xs
*Main> decimal [1,4,3,1,9]
14319
In Haskell, you have really powerfull weapon - functions for lists processing. One of these functions is foldl (we use strict version of foldl, foldl') It's type
foldl :: (a -> b -> a) -> a -> [b] -> a
This functions takes thre arguments, an accumulating agrument, a list processed, and, the most interest,
the function that perform any operation with accumulator and list element and returns the result. Fold is really significant function so you should read detail manual about it.
But, there is a problem, we have three variables it our equation: list element processed (x), total list length (n) and position of processed element (k). But we can traverse to foldl only one element.
How can we traverse position of each element? Let's form tuples from Int where first element is a position, and second is a value. It is a standard trick, zip function helps us:
zip [1..] [1,4,3,4,6]
[(1,1),(2,4),(3,3),(4,4),(5,6)]
Than we pass our list of tuples into foldl function, and foldl call lambda function (\sum (pos,x) -> (sum + x*(10^(l-pos)))) for each element of list, summing result in sum
I'm new in Haskell and try to solve 3 problem from http://projecteuler.net/.
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
My solution:
import Data.List
getD :: Int -> Int
getD x =
-- find deviders
let deriveList = filter (\y -> (x `mod` y) == 0) [1 .. x]
filteredList = filter isSimpleNumber deriveList
in maximum filteredList
-- Check is nmber simple
isSimpleNumber :: Int -> Bool
isSimpleNumber x = let deriveList = map (\y -> (x `mod` y)) [1 .. x]
filterLength = length ( filter (\z -> z == 0) deriveList)
in
case filterLength of
2 -> True
_ -> False
I try to run for example:
getD 13195
> 29
But when i try:
getD 600851475143
I get error Exception: Prelude.maximum: empty list Why?
Thank you #Barry Brown, I think i must use:
getD :: Integer -> Integer
But i get error:
Couldn't match expected type `Int' with actual type `Integer'
Expected type: [Int]
Actual type: [Integer]
In the second argument of `filter', namely `deriveList'
In the expression: filter isSimpleNumber deriveList
Thank you.
Your type signature limits the integer values to about 2^29. Try changing Int to Integer.
Edit:
I see that you already realised that you need to use Integer instead of Int. You need to change the types of both getD and isSimpleNumber otherwise you will get a type mismatch.
Also in general, if you are having trouble with types, simply remove the type declarations and let Haskell tell you the correct types.
Main> :t getD
getD :: Integral a => a -> a
Main> :t isSimpleNumber
isSimpleNumber :: Integral a => a -> Bool
After you found the error, may I point out that your solution is quite verbose? In this case a very simple implementation using brute force is good enough:
getD n = getD' n 2 where
getD' n f | n == f = f
| n `mod` f == 0 = getD' (n `div` f) f
| otherwise = getD' n (succ f)
this question is easy enough for brute-force solution, but it is a bad idea to do so because the whole idea of project euler is problems you need to really think of to solve (see end of answer)
so here are some of your program's flaws:
first, use rem instead of mod. it is more efficient.
some mathematical thinking should have told you that you don't need to check all numbers from 1 to x in the isprime function and the getD function, but checking all numbers from the squareroot to one (or reversed) should be sufficient. note that in getD you will actually need to filter numbers between x and the square root, because you search for the biggest one.
why do you use the maximum function in getD? you know the list is monotonically growing, so you may as well get the last one.
despite you only need the biggest divisor (which is prime) you compute the divisors list from small to big making the computer check for each value if it is a divisor or not although discarding the result once a bigger divisor is found. it should be fixed by filtering the list of numbers from x to 1, not from 1 to x. this will cause the computer to check divisibility (how should I say that?) for the biggest possible divisor, not throwing to the trash the knowledge of previous checks. note that this optimization takes effect only if the previous point is optimized, because otherwise the computer will compute all divisors anyway.
with the previous points mixed, you should have filtered all numbers [x,x-1 .. squareroot x] and taken the first.
you don't use an efficient isPrime function. if I were you, I would have searched for an isprime library function, which is guaranteed to be efficient.
and there are more..
with this kind of code you will never be able to solve harder project euler problems. they are designed to need extra thinking about the problem (for instance noticing you don't have to check numbers greater from the square root) and writing fast and efficient code. this is the purpose of project euler; being smart about programming. so don't skip it.