I'm trying to create a foldr example that converts an Integral to a list of digits (i.e., [Int]).
pickDigit num pos = (num `div` (10^pos)) `mod` 10
toDigits num = foldr (\pos acc -> (pickDigit num pos):acc) [] [0 .. floor (logBase 10 num)]
This loads successfully. But when I try to run it, for example
> toDigits 1234
I get a type error message I don't understand.
When I ask Haskell for the types of the loaded code and explicitly include those types in the source file, I get error messages on loading. When I try to explicitly restrict the types to Integer or Int, I get more error messages.
I'd appreciate some suggestions. Thanks.
logBase requires Floating, but it's not
This works:
[0 .. floor (logBase 10 $ fromIntegral num)]
Related
Ugh. The following code fails to compile:
factorsOf number = [(x, quot number x) | x <- [2..toInteger $ floor $ sqrt number], number `mod` x == 0]
The following error is thrown:
"No instance for (Floating Integer) arising from a use of `sqrt'"
Please help? I'm clearly not grokking Haskell coercion.
PS: Leaving off toInteger compiles but throws a type-ambiguity error at runtime.
It is highly advisable to always start design of a Haskell function with the type signature, and only then write the implementation. In this case, you probably want
factorsOf :: Integer -> [(Integer, Integer)]
So, within factorsOf n = ..., the variable n will have type Integer. That's the problem: you're trying to take the square root of an integer, but sqrt is only defined on floating numbers. So you need to convert to such a number before taking the root. After the root, you'll then want to truncate back to an integer, but floor already does that. toInteger is not needed.
factorsOf :: Integer -> [(Integer, Integer)]
factorsOf n
= [ (x, n`quot`x)
| x <- [2 .. floor . sqrt $ fromIntegral n]
, n `mod` x == 0
]
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.
This is not a duplicate question. Read below...
I'm declaring the following function:
divisors x = [(a, x/a) | a <- [2..(sqrt x)], x `mod` a == 0]
What I want to obtain is the divisors of x: A list of tuples that will contain (n, k) such as n * k = x
Example:
> divisors x
[(1,10), (2, 5)]
Why the above code isn't working?
It gives me the error:
*Main> divisors 10
<interactive>:1:0:
Ambiguous type variable `t' in the constraints:
`Floating t'
arising from a use of `divisors' at <interactive>:1:0-10
`Integral t'
arising from a use of `divisors' at <interactive>:1:0-10
Probable fix: add a type signature that fixes these type variable(s)
I've tried manually setting the signature of the function without success...
The problem is sqrt returns a Floating a, and you really just want integers when finding divisors. You can turn a Floating a into an Integral a with ceiling, floor or round. I will use ceiling, as I'm not sure if using floor or average won't skip a divisor.
The sqrt function also only accepts a floating number, so you will have to convert an integer into a floating before giving it to it (this can be done with fromIntegral).
Also, you use /, which also works with floating numbers. Using div is better as it works with integral numbers (rounding when necessary).
divisors x = [(a, x `div` a) | a <- [2..(ceiling $ sqrt $ fromIntegral x)], x `mod` a == 0]
With this, divisors 10 will give [(2,5)] (your code stops the (1,10) case from happening - I'm guessing this was intentional). Unfortunately you will get duplicates, eg divisors 12 will return [(2,6),(3,4),(4,3)], but that shouldn't be too hard to fix if it is a problem.
You can see the problem if you ask for the type:
divisors :: (Integral t, Floating t) => t -> [(t, t)]
and then check what things are both Integral and Floating:
Prelude> :info Floating
class Fractional a => Floating a where
instance Floating Float -- Defined in GHC.Float
instance Floating Double -- Defined in GHC.Float
and
Prelude> :info Integral
class (Real a, Enum a) => Integral a where
instance Integral Integer -- Defined in GHC.Real
instance Integral Int -- Defined in GHC.Real
so, it can be neither Int, Integer, Float or Double. You're in trouble...
Thankfully, we can convert between types, so that while sqrt needs a Floating, and mod needs an Integral (btw, rem is faster), we can either, e.g., do away with floating point division:
divisors :: Integer -> [(Integer, Integer)]
divisors x = [(a, x `div` a) | a <- [2..ceiling (sqrt (fromIntegral x))], x `rem` a == 0]
> divisors 100
[(2,0),(4,0),(5,0),(10,0)]
However, you need to think hard about what you really mean to do when converting integer types to floating point, via sqrt...
In Haskell, integer division and fractional division are different operations, and have different names. The slash operator, /, is for fractional division. Integer division is accomplished with div or quot (the difference between the two having to do with the behavior when there are negative numbers involved).
Try replacing x/a with
x `quot` a
instead.
The compiler error tells you exactly this: that you're treating a type sometimes as an integral number (by using mod), and sometimes as a fractional number (by using /), and it's not sure how to pick a type that acts like both of those.
You'll have a similar issue with sqrt, once that's sorted, though. There again, you need to be consistent about whether your types are integers or (in that case) floating point. For the purpose of finding possible divisors, it should suffice to range up to the greatest integer less that the floating point, so consider using floor (sqrt (fromIntegral x))). The fromIntegral converts x (which must have an integral type) to a different type -- in this case, it will default to Double. The floor then converts the Double result back into an integral type.
Instead of taking the square-root to bound the search, you can allow the comprehension to range over an infinite list, and use takeWhile to stop the search when the remainder is greater than the divisor:
divisors x = takeWhile (uncurry (<=)) [(a, x `div` a) | a <- [1..], x `mod` a == 0]
> divisors 100
[(1,100),(2,50),(4,25),(5,20),(10,10)]
Note: your original example shows (1,10) as one of the divisors of 10, so I started the comprehension from 1 instead of 2.
Hmm, this does search beyond the square-root until it hits the next factor above.
How about this:
divisors x = [(a, x `div` a) | a <- takeWhile ((<= x) . (^2)) [1..], x `mod` a == 0]
This is simple code designed to take a decimal number and return a string representing the equivalent in binary.
b2d :: Int -> String
b2d 1 = "1"
b2d x = show (x `mod` 2) ++ b2d x/2
However, when I try to run this through hugs, it gives me an error:
:3 - Instance of fractional [Char] required for definition of b2d
I don't know what this means. Can anyone tell me how to fix it?
Cheers.
you probably wanted (function calls have higher precedence than operators):
b2d (x/2)
also your first case should probably not take 2 arguments
/ is the fractional division operator. For integers, you need to use div (and add parentheses as newacct mentioned):
b2d x = show (x `mod` 2) ++ b2d (x `div` 2)
For extra efficiency points, use divMod to only perform one division:
b2d x = let (q,r) = x `divMod` 2
in show r ++ b2d q
I'm still new and trying to create a list for use in a function and want to keep it as small as possible which happens to be logBase x y.
but I'm having trouble getting logBase into something I can use in this list.
[1 .. (logBase x y)]
Any suggestions?
You don't post what type error you get, but I imagine it is something like this:
Prelude> let x = 2
Prelude> let y = 7
Prelude> [1 .. (logBase x y)]
<interactive>:1:7:
No instance for (Floating Integer)
arising from a use of `logBase' at <interactive>:1:7-17
Possible fix: add an instance declaration for (Floating Integer)
In the expression: (logBase x y)
In the expression: [1 .. (logBase x y)]
In the definition of `it': it = [1 .. (logBase x y)]
The problem is that:
Prelude> :t logBase
logBase :: (Floating a) => a -> a -> a
returns a type in the Floating class, while other variables in your program (1, 'x', 'y') are of integral type.
I presume you want a sequence of Integers?
Prelude> :set -XNoMonomorphismRestriction
Prelude> let x = 2
Prelude> let y = 42
Prelude> [1 .. truncate (logBase x y)]
[1,2,3,4,5]
Use truncate, celing or floor.
You probably want one of the functions list here. Hoogle and Hayoo! are great tools for this kind of thing since they let you put in the type of the function you want and get back a list of functions. With Haskell's rich type system this can be a very helpful tool, much more so than dynamically typed languages or even statically typed languages like C or Java.
You probably want some sort of rounding, truncate, floor, or ceiling function. Ints and Floats are different types (as you've seen) and the compiler won't let you mix them. I'll find a reference in a minute.