Instance of fractional [Char] required for definition? - string

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

Related

Adding two numbers together without using the + operator in Haskell

I want to add two positive numbers together without the use of any basic operators like + for addition. I've already worked my way around that (in the add''' function) (i think) may not be efficient but thats not the point right now. I am getting lots of type errors however which i have no idea how to handle, and is very confusing for me as it works on paper and i've come from python.
add 1245 7489
--add :: Int -> Int -> Int
add x y = add'' (zip (add' x) (add' y))
where
add' :: Int -> [Int]
add' 0 = []
add' x = add' (x `div` 10) ++ [x `mod` 10]
conversion [1,2,4,5] [7,4,8,9] then zipping them together [(1,7),(2,4)....]
add'' :: [(Int,Int)] -> [Int]
add'' (x:xs) = [(add''' (head x) (last x))] ++ add'' xs
summary [8,6,...] what happens when the sum reaches 10 is not implemented yet.
where
--add''' :: (Int,Int) -> Int
add''' x y = last (take (succ y) $ iterate succ x)
adding two numbers together
You can't use head and last on tuples. ...Frankly, you should never use these functions at all because they're unsafe (partial), but they can be used on lists. In Haskell, lists are something completely different from tuples.To get at the elements of a tuple, use pattern matching.
add'' ((x,y):xs) = [add''' x y] ++ add'' xs
(To get at the elements of a list, pattern matching is very often the best too.) Alternatively, you can use fst and snd, these do on 2-tuples what you apparently thought head and last would.
Be clear which functions are curried and which aren't. The way you write add''', its type signature is actually Int -> Int -> Int. That is equivalent to (Int, Int) -> Int, but it's still not the same to the type checker.
The result of add'' is [Int], but you're trying to use this as Int in the result of add. That can't work, you need to translate from digits to numbers again.
add'' doesn't handle the empty case. That's fixed easily enough, but better than doing this recursion at all is using standard combinators. In your case, this is only supposed to work element-wise anyway, so you can simply use map – or do that right in the zipping, with zipWith. Then you also don't need to unwrap any tuples at all, because it works with a curried function.
A clean version of your attempt:
add :: Int -> Int -> Int
add x y = fromDigits 0 $ zipWith addDigits (toDigits x []) (toDigits y [])
where
fromDigits :: Int -> [Int] -> Int
fromDigits acc [] = acc
fromDigits acc (d:ds)
= acc `seq` -- strict accumulator, to avoid thunking.
fromDigits (acc*10 + d) ds
toDigits :: Int -> [Int] -> [Int] -- yield difference-list,
toDigits 0 = id -- because we're consing
toDigits x = toDigits (x`div`10) . ((x`mod`10):) -- left-associatively.
addDigits :: Int -> Int -> Int
addDigits x y = last $ take (succ x) $ iterate succ y
Note that zipWith requires both numbers to have the same number of digits (as does zip).
Also, yes, I'm using + in fromDigits, making this whole thing pretty futile. In practice you would of course use binary, then it's just a bitwise-or and the multiplication is a left shift. What you actually don't need to do here is take special care with 10-overflow, but that's just because of the cheat of using + in fromDigits.
By head and last you meant fst and snd, but you don't need them at all, the components are right there:
add'' :: [(Int, Int)] -> [Int]
add'' (pair : pairs) = [(add''' pair)] ++ add'' pairs
where
add''' :: (Int, Int) -> Int
add''' (x, y) = last (take (succ y) $ iterate succ x)
= iterate succ x !! y
= [x ..] !! y -- nice idea for an exercise!
Now the big question that remains is what to do with those big scary 10-and-over numbers. Here's a thought: produce a digit and a carry with
= ([(d, 0) | d <- [x .. 9]] ++ [(d, 1) | d <- [0 ..]]) !! y
Can you take it from here? Hint: reverse order of digits is your friend!
the official answer my professor gave
works on positive and negative numbers too, but still requires the two numbers to be the same length
add 0 y = y
add x y
| x>0 = add (pred x) (succ y)
| otherwise = add (succ x) (pred y)
The other answers cover what's gone wrong in your approach. From a theoretical perspective, though, they each have some drawbacks: they either land you at [Int] and not Int, or they use (+) in the conversion back from [Int] to Int. What's more, they use mod and div as subroutines in defining addition -- which would be okay, but then to be theoretically sound you would want to make sure that you could define mod and div themselves without using addition as a subroutine!
Since you say efficiency is no concern, I propose using the usual definition of addition that mathematicians give, namely: 0 + y = y, and (x+1) + y = (x + y)+1. Here you should read +1 as a separate operation than addition, a more primitive one: the one that just increments a number. We spell it succ in Haskell (and its "inverse" is pred). With this theoretical definition in mind, the Haskell almost writes itself:
add :: Int -> Int -> Int
add 0 y = y
add x y = succ (add (pred x) y)
So: compared to other answers, we can take an Int and return an Int, and the only subroutines we use are ones that "feel" more primitive: succ, pred, and checking whether a number is zero or nonzero. (And we land at only three short lines of code... about a third as long as the shortest proposed alternative.) Of course the price we pay is very bad performance... try add (2^32) 0!
Like the other answers, this only works for positive numbers. When you are ready for handling negative numbers, we should chat again -- there's some fascinating mathematical tricks to pull.

Unresolved top level overloading

Task is to find all two-valued numbers representable as the sum of the sqrt's of two natural numbers.
I try this:
func = [sqrt (x) + sqrt (y) | x <- [10..99], y <- [10..99], sqrt (x) `mod` 1 == 0, sqrt (y) `mod` 1 == 0]
Result:
Unresolved top-level overloading Binding : func
Outstanding context : (Integral b, Floating b)
How can I fix this?
This happens because of a conflict between these two types:
sqrt :: Floating a => a -> a
mod :: Integral a => a -> a -> a
Because you write mod (sqrt x) 1, and sqrt is constrained to return the same type as it takes, the compiler is left trying to find a type for x that simultaneously satisfies the Floating constraint of sqrt and the Integral constraint of mod. There are no types in the base library that satisfy both constraints.
A quick fix is to use mod' :: Real a => a -> a -> a:
import Data.Fixed
func = [sqrt (x) + sqrt (y) | x <- [10..99], y <- [10..99], sqrt (x) `mod'` 1 == 0, sqrt (y) `mod'` 1 == 0]
However, from the error you posted, it looks like you may not be using GHC, and mod' is probably a GHC-ism. In that case you could copy the definition (and the definition of the helper function div') from here.
But I recommend a more involved fix. The key observation is that if x = sqrt y, then x*x = y, so we can avoid calling sqrt at all. Instead of iterating over numbers and checking if they have a clean sqrt, we can iterate over square roots; their squares will definitely have clean square roots. A straightforward application of this refactoring might look like this:
sqrts = takeWhile (\n -> n*n <= 99)
. dropWhile (\n -> n*n < 10)
$ [0..]
func = [x + y | x <- sqrts, y <- sqrts]
Of course, func is a terrible name (it's not even a function!), and sqrts is a constant we could compute ourselves, and is so short we should probably just inline it. So we might then simplify to:
numberSums = [x + y | x <- [4..9], y <- [4..9]]
At this point, I would be wondering whether I really wanted to write this at all, preferring just
numberSums = [8..18]
which, unlike the previous iteration, doesn't have any duplicates. It has lost all of the explanatory power of why this is an interesting constant, though, so you would definitely want a comment.
-- sums of pairs of numbers, each of whose squares lies in the range [10..99]
numberSums = [8..18]
This would be my final version.
Also, although the above definitions were not parameterized by the range to search for perfect squares in, all the proposed refactorings can be applied when that is a parameter; I leave this as a good exercise for the reader to check that they have understood each change.

Haskell Numeric Type Frustration

I'm having an issue with a simple Haskell program. It's supposed to factor a number n-1 into the form (2^r)s where n is a Carmichael number. This isn't really pertinent to my question, but it's what the following set of functions aims to do.
divides::Int->Int->Bool
divides x y = not $ y `mod` x == 0
carmichaeltwos::Int->Int
carmichaeltwos n
| not $ divides 2 n =0
| otherwise = (+ 1) $ carmichaeltwos (n/2)
carmichaelodd::Int->Int
carmichaelodd n
| not $ divides 2 n = n
| otherwise = carmichaelodd (n/2)
factorcarmichael::Int->(Int, Int)
factorcarmichael n = (r, s)
where
nminus = n-1
r = carmichaeltwos nminus
s = carmichaelodd nminus
When I try to load this into GHCi, Haskell spits up:
No instance for (Fractional Int)
arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Int)
In the first argument of `carmichaelodd', namely `(n / 2)'
In the expression: carmichaelodd (n / 2)
In an equation for `carmichaelodd':
carmichaelodd n
| not $ divides 2 n = n
| otherwise = carmichaelodd (n / 2)
I know that the function / has type (/)::(Fractional a)=>a->a->a, but I don't see how to fix my program to make this work nicely.
Also, I realize that I'm basically computing the same thing twice in the factorcarmichael function. I couldn't think of any easy way to factor the number in one pass and get the tuple I want as an answer.
To divide two Ints when you know, as in this case, that the dividend is divisible by the divisor, use the div or quot function, i.e., div n 2 or quot n 2. (div and quot differ only in their handling of negative operands when the "true" quotient isn't an integer.)
Also, why are you defining divides as not $ mod y x == 0? Unless you're using a nonstandard meaning of "divides," you should be using just mod y x == 0 — x divides y iff y modulo x is zero.
As for combining carmichaeltwos and carmichaelodd, try using the until function:
factorcarmichael n = until (\(_, s) -> not $ divides 2 s)
(\(r, s) -> (r+1, div s 2))
(0, n-1)

Haskell: What is the source of error "Ambiguous type variable ... `Integral t' ... `RealFrac t' ..." in this code?

[Disclaimer] I am very new to Haskell (and any FPL for that matter), just started learning today by reading YAHT. So my code might look "funny". Any help to improve the coding style would be appreciated as well.
I was trying to write a function in Haskell that generates a list with series 1 to n for a given value of n, starting with +1 and toggling the sign first after 1 number, then 2, then 3 and so on.
e.g. series 16 should produce [1,-2,-3,4,5,6,-7,-8,-9,-10,11,12,13,14,15,-16] (1 positive, 2 negative, 3 positive, 4 negative, ...).
I found that the sign changes after each triangular number, which equals the sum of first few natural numbers.
So I wrote this code:
module Test
where
--It accepts n and k, prints numbers 1 to n, starting with +1 and toggling their sign after each triangular number
series 0 = []
series n =
if isTriangular n
then series (getPrevTri n (n-1)) ++ getSeries (odd (n + (getPrevTri n (n-1)))) ((getPrevTri n (n-1)) + 1) (n - (getPrevTri n (n-1)))
else series (getPrevTri n (n-1)) ++ getSeries (odd ((getNextTri n (n+1)) + (getPrevTri n (n-1)))) ((getPrevTri n (n-1)) + 1) (n - (getPrevTri n (n-1)))
--The sign is negative for those numbers which follow an odd triangular number AND the triangular number previous to it is even
--OR an even number AND the triangular number previous to it is odd.
getSeries sign start 0 = []
getSeries sign start n =
if sign == True
then [start] ++ getSeries True (start+1) (n-1)
else [-start] ++ getSeries False (start+1) (n-1)
--Checks whether n is a triangular number or not
isTriangular 0 = False
isTriangular n =
checkSum n 1
--Checks whether n is equal to sum of first few natural numbers, starting from k
checkSum n 0 = False
checkSum n k =
if n == (k * k + k)/ 2
then True
else if n > (k * k + k)/ 2
then checkSum n (k+1)
else False
--Gets the triangular number just smaller than n, descending from k
getPrevTri 0 k = 0
getPrevTri n k =
if k <= n
then if isTriangular k
then truncate k
else getPrevTri n (k-1)
else 0
--Gets the triangular number just greater than n, starting from k
getNextTri 0 k = 1
getNextTri n k =
if k >= n
then if isTriangular k
then truncate k
else getNextTri n (k+1)
else 0
I had to add a call to "truncate" in "getPrevTri" and "gerNextTri" since it started producing fractional numbers. But still I'm getting this error:
*Test> :load "Test.hs"
[1 of 1] Compiling Test ( Test.hs, interpreted )
Ok, modules loaded: Test.
*Test> series 16
<interactive>:1:0:
Ambiguous type variable `t' in the constraints:
`Integral t' arising from a use of `series' at <interactive>:1:0-8
`RealFrac t' arising from a use of `series' at <interactive>:1:0-8
Probable fix: add a type signature that fixes these type variable(s)
*Test>
Could someone explain what is the source of this error?
And what does surprise me is that when I tried to debug this code, I modified it to http://pastebin.ca/1932564 which produced the similar error.
And then to http://pastebin.ca/1932556 and it surprisingly caused no error.
(Please find the output at the end of the respective posts.)
What I infer from it is that a call to
isTriangular n
causes a type error in
odd n
How is it possible when Haskell is a "pure" FPL and in which functions do not have any side effects?
I used GHCi, version 6.12.3 for these codes, on a Windows 7 x64 machine.
There is no numerical type which implements both Integral (forced by odd) and RealFrac (forced by (/)). (These are typeclasses, if you don't know what I'm talking about, just wait until your tutorial shows about this)
You may replace either / by div or do an explicit cast via fromIntegral or similar. You may also do something like x/2 == 1 instead of odd x.
Edit: In your second pastebin file, you did the conversions via truncate, which is also possible.
Haskell strength is it's strong typing system, allowing you to do less programming errors but also involves the problem of having strange problem at obvious places. I would generally suggest you to provide type-informations at least at toplevel functions. (like myFunc :: Int -> Integer). This improves both readability and safety, as the compiler prompts you suddently if something went wrong. In ghci, you can easily find out about type informations via the :t command:
ghci> :t odd
odd :: (Integral a) => a -> Bool
Please notice, that you have to wrap parantheses around infix functions when using this:
ghci> :t ($)
($) :: (a -> b) -> a -> b
Because FUZxxI already gave you an answer you were looking for I will show you how your problem can be solved easier and a lot shorter. Just for information.
How would you solve your problem in your head? First, you have to 'generate' sequence containing [1,2,2,3,3,3,4,4,4,4 ... ] just to know where to change sign. That sequence, expressed in Haskell notation, would be -
numbers = concatMap (\x -> replicate x x) [1..]
Then you have to 'combine' each number of this sequence with corresponding number from sequence from 1 to n to give it proper sign - that would be -
series n = zipWith (\a b -> a*(-1)^(b `mod` 2 + 1)) [1..n] numbers
Well, and that's it. You have the solution. You can even express it as one-liner without using numbers variable. But i consider it less readable.

How do I get the sums of the digits of a large number in Haskell?

I'm a C++ Programmer trying to teach myself Haskell and it's proving to be challenging grasping the basics of using functions as a type of loop. I have a large number, 50!, and I need to add the sum of its digits. It's a relatively easy loop in C++ but I want to learn how to do it in Haskell.
I've read some introductory guides and am able to get 50! with
sum50fac.hs::
fac 0 = 1
fac n = n * fac (n-1)
x = fac 50
main = print x
Unfortunately at this point I'm not entirely sure how to approach the problem.
Is it possible to write a function that adds (mod) x 10 to a value and then calls the same function again on x / 10 until x / 10 is less than 10? If that's not possible how should I approach this problem?
Thanks!
sumd 0 = 0
sumd x = (x `mod` 10) + sumd (x `div` 10)
Then run it:
ghci> sumd 2345
14
UPDATE 1:
This one doesn't generate thunks and uses accumulator:
sumd2 0 acc = acc
sumd2 x acc = sumd2 (x `div` 10) (acc + (x `mod` 10))
Test:
ghci> sumd2 2345 0
14
UPDATE 2:
Partially applied version in pointfree style:
sumd2w = (flip sumd2) 0
Test:
ghci> sumd2w 2345
14
I used flip here because function for some reason (probably due to GHC design) didn't work with accumulator as a first parameter.
Why not just
sumd = sum . map Char.digitToInt . show
This is just a variant of #ony's, but how I'd write it:
import Data.List (unfoldr)
digits :: (Integral a) => a -> [a]
digits = unfoldr step . abs
where step n = if n==0 then Nothing else let (q,r)=n`divMod`10 in Just (r,q)
This will product the digits from low to high, which while unnatural for reading, is generally what you want for mathematical problems involving the digits of a number. (Project Euler anyone?) Also note that 0 produces [], and negative numbers are accepted, but produce the digits of the absolute value. (I don't want partial functions!)
If, on the other hand, I need the digits of a number as they are commonly written, then I would use #newacct's method, since the problem is one of essentially orthography, not math:
import Data.Char (digitToInt)
writtenDigits :: (Integral a) => a -> [a]
writtenDigits = map (fromIntegral.digitToInt) . show . abs
Compare output:
> digits 123
[3,2,1]
> writtenDigits 123
[1,2,3]
> digits 12300
[0,0,3,2,1]
> writtenDigits 12300
[1,2,3,0,0]
> digits 0
[]
> writtenDigits 0
[0]
In doing Project Euler, I've actually found that some problems call for one, and some call for the other.
About . and "point-free" style
To make this clear for those not familiar with Haskell's . operator, and "point-free" style, these could be rewritten as:
import Data.Char (digitToInt)
import Data.List (unfoldr)
digits :: (Integral a) => a -> [a]
digits i = unfoldr step (abs i)
where step n = if n==0 then Nothing else let (q,r)=n`divMod`10 in Just (r,q)
writtenDigits :: (Integral a) => a -> [a]
writtenDigits i = map (fromIntegral.digitToInt) (show (abs i))
These are exactly the same as the above. You should learn that these are the same:
f . g
(\a -> f (g a))
And "point-free" means that these are the same:
foo a = bar a
foo = bar
Combining these ideas, these are the same:
foo a = bar (baz a)
foo a = (bar . baz) a
foo = bar . baz
The laster is idiomatic Haskell, since once you get used to reading it, you can see that it is very concise.
To sum up all digits of a number:
digitSum = sum . map (read . return) . show
show transforms a number to a string. map iterates over the single elements of the string (i.e. the digits), turns them into a string (e.g. character '1' becomes the string "1") and read turns them back to an integer. sum finally calculates the sum.
Just to make pool of solutions greater:
miterate :: (a -> Maybe (a, b)) -> a -> [b]
miterate f = go . f where
go Nothing = []
go (Just (x, y)) = y : (go (f x))
sumd = sum . miterate f where
f 0 = Nothing
f x = Just (x `divMod` 10)
Well, one, your Haskell function misses brackets, you need fac (n - 1). (oh, I see you fixed that now)
Two, the real answer, what you want is first make a list:
listdigits n = if n < 10 then [n] else (listdigits (n `div` 10)) ++ (listdigits (n `mod` 10))
This should just compose a list of all the digits (type: Int -> [Int]).
Then we just make a sum as in sum (listdigits n). And we should be done.
Naturally, you can generalize the example above for the list for many different radices, also, you can easily translate this to products too.
Although maybe not as efficient as the other examples, here is a different way of approaching it:
import Data.Char
sumDigits :: Integer -> Int
sumDigits = foldr ((+) . digitToInt) 0 . show
Edit: newacct's method is very similar, and I like it a bit better :-)

Resources