Implementing Collatz Function - haskell

Learn You a Haskell mentions the Collatz Sequences:
We take a natural number. If that number is even, we divide it by two.
If it's odd, we multiply it by 3 and then add 1 to that.
When I tried to implement it, I ran into a problem
collatz :: (Integral a) => a -> [a]
collatz x
| odd x = f x : collatz (f x)
| otherwise = g x : collatz (g x)
where f y = y*3 + 1
g y = y/2
But I get this compile-time error:
CollatzSeq.hs:10:16:
Could not deduce (Fractional a) arising from a use of `g'
from the context (Integral a)
bound by the type signature for collatz :: Integral a => a -> [a]
at CollatzSeq.hs:7:12-35
Possible fix:
add (Fractional a) to the context of
the type signature for collatz :: Integral a => a -> [a]
In the first argument of `(:)', namely `g x'
In the expression: g x : collatz (g x)
In an equation for `collatz':
collatz x
| odd' x = f x : collatz (f x)
| otherwise = g x : collatz (g x)
where
f y = y * 3 + 1
g y = y / 2
As I understand, the problem is that calling collatz (g x) can return a Fractional since y / 2 returns a Double:
Prelude> let x = 4 / 2
Prelude> :t x
x :: Double
I tried to fix this type error by adding floor in front of the y/2, but that didn't work.
Please tell me how to fix this error.

Use div instead of (/). Alternately, if you want another rounding strategy than floor, you may use fromIntegral, as in
round (fromIntegral y / 2)

The error comes from the way / is defined. GHCI shows this result for :t (/):
(/) :: Fractional a => a -> a -> a
An alternative would be to use div, which has the type signature:
div :: Integral a => a -> a -> a
Secondly, you are skipping the input term in your current implementation. That should not be the case.
Finally, you need to add the base case for input = 1, otherwise your function will get caught in an infinite loop. You may change it to:
collatz :: (Integral a) => a -> [a]
collatz 1 = [1]
collatz x
| odd x = x : collatz (f x)
| otherwise = x : collatz (g x)
where f y = y*3 + 1
g y = y `div` 2

Related

(Haskell) How to convert from Ratio Integer to Ratio Rational?

How does addition of two different ratios work? For instance, ratio integer and ratio rationals don't seem to get added. I tried evaluating the continued fraction for a given list.
Here's the code :
import Data.Ratio
f :: [Integer] -> Rational
f(x:xs)
| (null xs == True) = x
| otherwise = x + (1 % f xs)
What is the correct version of the code supposed to be? Since f yields a Ratio Rational, I feel that x, if type-casted to a Ratio rational number, will suffice.
No type conversion needed, use proper division between rationals.
import Data.Ratio
f :: [Integer] -> Rational
f [] = error "empty list"
f [x] = x % 1
f (x:xs#(_:_)) = x % 1 + 1 / f xs
Here, x % 1 makes x into a Rational (ok, that's conversion, if you want). We could also have used fromInteger, I think.
Then, between Rational values, we do not use % which produces a weird Ratio Rational, but we exploit / which produces a Rational instead.
Converting x to a Rational will not be sufficient here. Since you here write 1 % f xs. The type of (%) is (%) :: Integral a => a -> a -> Ratio a, and since f xs is a Rational, and Rational is not an instance of Integral, we thus need to fix a second issue.
It is however not that hard. We can for example make a function that calculates the inverse:
inverseR :: Integral a => Ratio a -> Ratio a
inverseR r = denominator r % numerator r
Since Ratio a is an instance of Num given a is an instance of Integral, we can use fromInteger :: Num a => Integer -> a:
f :: [Integer] -> Rational
f [x] = fromInteger x
f (x:xs) = fromInteger x + inverseR (f xs)
For example:
Prelude Data.Ratio> f [1,4,2,5]
60 % 49
Since 1 + 1/(4 + 1/(2 + 1/5)) = 1 + 1/(4 + 1/(11/5)) = 1 + 1/(4 + 5/11) = 1 + 1/(49/11) = 1 + 11/49 = 60 / 49.
We can further improve this by:
using fromIntegral :: (Integral a, Num b) => a -> b to convert any integral to a Ratio; and
by using (/) :: Fractional a => a -> a -> a.
We thus can generalize this to a function:
f :: (Integral a, Fractional b) => [a] -> b
f [x] = fromIntegral x
f (x:xs) = fromIntegral x + 1 / f xs
Which yields the same value:
Prelude Data.Ratio> f [1,4,2,5] :: Rational
60 % 49
We can use a foldr pattern, and avoid the explicit recursion:
f :: (Integral a, Fractional b) => [a] -> b
f = foldr1 (\x -> (x +) . (1 /)) . map fromIntegral

Why is there an error for the third let-in statement?

Prelude> let [x,y] = [3,4] in x*x+y*y
25
Prelude> let x:[y] = [3,4] in x*x + y*y
25
Prelude> let x:y = 3:4 in x*x+y*y
interactive:6:5: error:
* Non type-variable argument in the constraint: Num [a]
(Use FlexibleContexts to permit this)
* When checking the inferred type
x :: forall a. (Num a, Num [a]) => a
In the expression: let x : y = 3 : 4 in x * x + y * y
In an equation for `it': it = let x : y = 3 : 4 in x * x + y * y
Can someone explain what is happening in the first two statements and why is there an error for the third let ... in .. statement.
In the third example, the right-hand-side of the let assignment is: 3:4. The : (cons) operator has the type signature a -> [a] -> [a]: it takes a value on its left side, and a list of that type of value on the right side. In this case, 3 is an a, but 4 is not a list of a ([a]); it is also an a. This is invalid.
Given the form of your exercise so far, there are two ways that you can fix this expression: with 3:[4] or with 3:4:[].
If you tried running your code now, you would see that it fails on x * x + y * y. This is because your pattern-match assigns x to 3, and y to [4] (a singleton list). A list cannot be multiplied by itself, nor can it be added to a number. So once more, we use the solution for the right-hand-side, on the left-hand-side:
let x:y:[] = 3:4:[]
in x * x + y * y
If we add a few too many type annotations, you can hopefully see where things are going wrong:
-- These work fine
-- let [x, y] = [3, 4] in ...
example1 = let [(x :: a), (y :: a)] :: [a]
= [(3 :: a), (4 :: a)] :: [a]
in x * x + y * y
-- let x:[y] = [3, 4] in ...
example2 = let ((x :: a) : ([(y :: a)] :: [a])) :: [a]
in x * x + y * y
-- This is the incorrect implementation
-- let x:y = 3:4 in ...
example3 :: (Num a) => a
example3 = let (x :: a) : (y :: [a]) -- (:) :: a -> [a] -> [a]
= (3 :: a) : (4 :: a) -- 4 :: a is invalid here: require [a]
in (x :: a) * (x :: a)
+ (y :: [a]) * (y :: [a]) -- Trying to multiply two lists
-- This is the fixed implementation
-- let x:y:[] = 3:4:[] in ...
example3' :: (Num a) => a
example3' = let ((x :: a) : (y :: a) : ([] :: [a])) :: [a]
= ((3 :: a) : (4 :: a) : ([] :: [a])) :: [a]
in x * x + y * y

Haskell - From generic to Integer | No instance for (RealFrac Integer) arising from a use of ‘floor’

I'm learning haskell.
I'm trying to solve a problem in which you're given a number (n) and you have to find a pair (m, k) where m^k would make n a perfect power.
n is a perfect power if there exist natural numbers m > 1, and k > 1
such that m^k = n.
This is what I came up with so far
module Test where
isPerfectPowerOf :: (Floating p, Enum p, RealFrac p) => p -> Maybe [(p, p)]
isPerfectPowerOf i
| null perfectList = Nothing
| otherwise = Just perfectList
where perfectList = filter (\(x, _) -> floor x == x) [(logBase x i, x) | x <- [2 .. (i - 1)]]
and it works.
But as you can see, with very generic types. What I want is for it to work with
isPerfectPowerOf :: Integer -> Maybe [(Integer, Integer)]
So for debugging purposes I placed this signature over the code which gave me these errors
severity: 'Error'
message: ' • No instance for (RealFrac Integer) arising from a use of ‘floor’
• In the first argument of ‘(==)’, namely ‘floor x’
In the expression: floor x == x
In the first argument of ‘filter’, namely
‘(\ (x, _) -> floor x == x)’
severity: 'Error'
message: ' • No instance for (Floating Integer)
arising from a use of ‘logBase’
• In the expression: logBase x i
In the expression: (logBase x i, x)
In the second argument of ‘filter’, namely
‘[(logBase x i, x) | x <- [2 .. (i - 1)]]’
So if I'm not completely off the mark I'll need to somehow typecast floor's and logBase's inputs properly.
floor :: (RealFrac a, Integral b) => a -> b
logBase :: Floating a => a -> a -> a
How should I go about doing it?
Or if it isn't the problem what could be?
So you tried:
perfectList :: Integer -> [(Integer, Integer)]
perfectList i = filter (\(x, _) -> floor x == x) [(logBase x i, x) | x <- [2 .. (i - 1)]]
(I'm going to deal with perfectList here for the sake of brevity. Note, though, that the conversion to Maybe in isPerfectPowerOf is perhaps redundant, as the nothingness of the Maybe result is equivalent to the emptiness of the list.)
That results in the two type errors you quoted. The first one arises because the argument to floor must be of some RealFrac type, and Integral isn't one of them. Similarly, the second error arises because logBase takes and returns values of some Floating type (and so you need to not only convert the arguments to floating-point but also convert the result back to Integer). Performing these adjustments results in:
perfectList :: Integer -> [(Integer, Integer)]
perfectList i = fmap (\(k, x) -> (floor k, x))
. filter (\(k, _) -> fromIntegral (floor k) == k)
$ [(logBase (fromIntegral x) (fromIntegral i), x) | x <- [2 .. (i - 1)]]
(Note that I have renamed your log variable, for the sake of clarity; you might also want to swap the order of the elements in the pairs.)
Since you are using a list comprehension already, it is easier to shift the fmap and the filter into it:
perfectList :: Integer -> [(Integer, Integer)]
perfectList i = [(k', x) | x <- [2 .. (i - 1)]
, let k = logBase (fromIntegral x) (fromIntegral i), let k' = floor k
, fromIntegral k' == k
]
On a final note, using floor to check whether a floating-point number is "really" a round number isn't fully reliable:
GHCi> fromIntegral (floor (logBase 2 (2**29))) == logBase 2 (2**29)
False
That being so, an ultimately sounder approach would be switching to an algorithm that finds perfect powers using integer arithmetic throughout, thus avoiding floating-point altogether. (While I suspect you'd want to implement that yourself, for an off-the-shelf solution check the Math.NumberTheory.Powers module from the arithmoi package.)

What is happening when I compose * with + in Haskell?

I'm trying to understand the result of
(*) . (+)
in Haskell. I know that the composition operator is just the standard composition of mathematical functions- so
(f . g) = f (g x)
But:
(*) . (+) :: (Num (a -> a), Num a) => a -> (a -> a) -> a -> a
I'm struggling to understand this type signature. I would have expected to be able to do things like:
((*) . (+)) 1 2 :: Num a => a -> a
= (* (+ 1 2))
What is the meaning of (*) . (+)'s type signature? I tried playing with it by something like (just matching up with its signature):
((*) . (+)) 1 (\x -> x + 1) 1
But that fails to compile. I'm trying to walk through the logical steps when composing these, but I'm not fully understanding how it's getting to this result (and what the result is).
I understand how you feel. I found function composition to be quite difficult to grasp at first too. What helped me grok the matter were type signatures. Consider:
(*) :: Num x => x -> x -> x
(+) :: Num y => y -> y -> y
(.) :: (b -> c) -> (a -> b) -> a -> c
Now when you write (*) . (+) it is actually the same as (.) (*) (+) (i.e. (*) is the first argument to (.) and (+) is the second argument to (.)):
(.) :: (b -> c) -> (a -> b) -> a -> c
|______| |______|
| |
(*) (+)
Hence the type signature of (*) (i.e. Num x => x -> x -> x) unifies with b -> c:
(*) :: Num x => x -> x -> x -- remember that `x -> x -> x`
| |____| -- is implicitly `x -> (x -> x)`
| |
b -> c
(.) (*) :: (a -> b) -> a -> c
| |
| |‾‾‾‾|
Num x => x x -> x
(.) (*) :: Num x => (a -> x) -> a -> x -> x
Hence the type signature of (+) (i.e. Num y => y -> y -> y) unifies with Num x => a -> x:
(+) :: Num y => y -> y -> y -- remember that `y -> y -> y`
| |____| -- is implicitly `y -> (y -> y)`
| |
Num x => a -> x
(.) (*) (+) :: Num x => a -> x -> x
| | |
| |‾‾‾‾| |‾‾‾‾|
Num y => y y -> y y -> y
(.) (*) (+) :: (Num (y -> y), Num y) => y -> (y -> y) -> y -> y
I hope that clarifies where the Num (y -> y) and Num y come from. You are left with a very weird function of the type (Num (y -> y), Num y) => y -> (y -> y) -> y -> y.
What makes it so weird is that it expects both y and y -> y to be instances of Num. It's understandable that y should be an instance of Num, but how y -> y? Making y -> y an instance of Num seems illogical. That can't be correct.
However, it makes sense when you look at what function composition actually does:
( f . g ) = \z -> f ( g z)
((*) . (+)) = \z -> (*) ((+) z)
So you have a function \z -> (*) ((+) z). Hence z must clearly be an instance of Num because (+) is applied to it. Thus the type of \z -> (*) ((+) z) is Num t => t -> ... where ... is the type of (*) ((+) z), which we will find out in a moment.
Therefore ((+) z) is of the type Num t => t -> t because it requires one more number. However, before it is applied to another number, (*) is applied to it.
Hence (*) expects ((+) z) to be an instance of Num, which is why t -> t is expected to be an instance of Num. Thus the ... is replaced by (t -> t) -> t -> t and the constraint Num (t -> t) is added, resulting in the type (Num (t -> t), Num t) => t -> (t -> t) -> t -> t.
The way you really want to combine (*) and (+) is using (.:):
(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
f .: g = \x y -> f (g x y)
Hence (*) .: (+) is the same as \x y -> (*) ((+) x y). Now two arguments are given to (+) ensuring that ((+) x y) is indeed just Num t => t and not Num t => t -> t.
Hence ((*) .: (+)) 2 3 5 is (*) ((+) 2 3) 5 which is (*) 5 5 which is 25, which I believe is what you want.
Note that f .: g can also be written as (f .) . g, and (.:) can also be defined as (.:) = (.) . (.). You can read more about it here:
What does (f .) . g mean in Haskell?
(*) and (+) both have the type signature Num a => a -> a -> a
Now, if you compose them, you get something funky.
(*) . (+) :: (Num (a -> a), Num a) => a -> (a -> a) -> a -> a
That's because (*) and (+) are expecting two 'arguments'.
(+) with one argument gets you a function. The . operator expects that function (the a -> a that you see).
Here's the meaning of (*) . (+)
x f y
(*) . (+) :: (Num (a -> a), Num a) => a -> (a -> a) -> a -> a
(*) . (+) maps x f y to ((x +) * f) y where f is a function from a to a that is ALSO a number.
The reason (*) expects a function is to make the types match while it expects two arguments, but that function has to be a number because (*) only works on numbers.
Really, this function makes no sense at all.
Some extensions first:
{-# LANGUAGE FlexibleContexts, FlexibleInstances, TypeSynonymInstances #-}
As the other answers show, your function is
weird :: (Num (a -> a), Num a) => a -> (a -> a) -> a -> a
weird x g = (x +) * g
But this function does have non-weird semantics.
There is a notion of difference lists. Accordingly, there is a notion of difference integers. I've seen them being used only in the dependently typed setting (e.g. here, but that's not the only case). The relevant part of the definition is
instance Enum DiffInt where
toEnum n = (n +)
fromEnum n = n 0
instance Num DiffInt where
n + m = n . m
n * m = foldr (+) id $ replicate (fromEnum n) m
This doesn't make much sense in Haskell, but can be useful with dependent types.
Now we can write
test :: DiffInt
test = toEnum 3 * toEnum 4
Or
test :: DiffInt
test = weird 3 (toEnum 4)
In both the cases fromEnum test == 12.
EDIT
It's possible to avoid the using of the TypeSynonymInstances extension:
{-# LANGUAGE FlexibleContexts, FlexibleInstances #-}
weird :: (Num (a -> a), Num a) => a -> (a -> a) -> a -> a
weird x g = (x +) * g
instance (Enum a, Num a) => Enum (a -> a) where
toEnum n = (toEnum n +)
fromEnum n = fromEnum $ n (toEnum 0)
instance (Enum a, Num a) => Num (a -> a) where
n + m = n . m
n * m = foldr (+) id $ replicate (fromEnum n) m
type DiffInt = Int -> Int
As before we can write
test' :: DiffInt
test' = weird 3 (toEnum 4)
But now we can also write
-- difference ints over difference ints
type DiffDiffInt = DiffInt -> DiffInt
test'' :: DiffDiffInt
test'' = weird (toEnum 3) (toEnum (toEnum 4))
And
main = print $ fromEnum $ fromEnum test'
prints 12.
EDIT2 Better links added.
Let:
m = (*)
a = (+)
then
(m.a) x = (m (a x)) = m (a x)
Now m expects a Num a as a parameter, on the other hand (a x) , i.e. (x +) is a unary function (a -> a) by definition of (+). I guess what happened is that GHC tries to unite these two types so that, if you have a type that is both a number and a unary function, m can take a number and a unary function and return a unary function, since they are considered the same type.
As #Syd pointed, this unification wouldn't make sense for any normal number types such as integers and floating point numbers.
There are good answers here, but let me quickly point out a few steps where you went wrong.
First, the correct definition of function composition is
(f . g) x = f (g x)
you omitted the x on the LHS. Next, you should remember that in Haskell h x y is the same as (h x) y. So, contrary to what you expected,
((*) . (+)) 1 2 = (((*) . (+)) 1) 2 = ((*) ((+) 1)) 2 = ((+) 1) * 2,
and now you see why that fails. Also,
((*) . (+)) 1 (\x -> x + 1) 1
does not work, because the constraint Num (Int -> Int) is not satisfied.

Why does Haskell want this function's argument to have the type classes (RealFrac x, Integral x) when it only needs to be Integral x?

I'm trying to write some code that does a complete factorization of an integer by trial division. This code seems like it ought to work:
findAFact :: Integral x => x -> x
findAFact x = searchInts [2, 3..] x where
searchInts (int:ints) div
| div `mod` int == 0 = int
| otherwise = searchInts ints div
completeFacts :: Integral x => x -> [x]
completeFacts x = tryForFact [] x where
tryForFact fs x = if x == 1
then fs
else let fact = findAFact x
in tryForFact (fact:fs) (floor ((fromIntegral x) / fact))
but if I try to compile this I get the following error:
Could not deduce (RealFrac x) arising from a use of 'tryForFact'
from the context (Integral x)
bound by the type signature for
completeFacts :: Integral x => x -> [x]
at 5.hs:26:18-39
Possible fix:
add (RealFrac x) to the context of
the type signature for completeFacts :: Integral x => x -> [x]
In the expression: tryForFact [] x
In an equation for 'completeFacts':
completeFacts x
= tryForFact [] x
where
tryForFact fs x
= if x == 1 then
fs
else
let ... in tryForFact (fact : fs) (floor ((fromIntegral x) / fact))
If I remove the type signature from completeFacts and try loading it into GHCI, the interpreter loads the file and supplies the type signature (RealFrac x, Integral x ) => x -> [x] for completeFacts, but then complains when I try to use completeFacts that there's no way to show it because its type is ambiguous in the context of show. That makes sense to me because it seems like there would be a clear way to display x as a RealFrac or an Integral, but not both.
This seems to be the offending code:
...
in tryForFact (fact:fs) (floor ((fromIntegral x) / fact))
I'm confused because I'd imagine passing x through fromIntegral and then passing the result of the division into floor would give me an Integral back. I don't see why Haskell still thinks x also needs to have the type class RealFrac. Why does Haskell insist on this, and how can I rewrite completeFacts so that x can just be an Integral?
Thanks!
It's because you didn't convert fact to a RealFrac before doing division:
in tryForFact (fact:fs) (floor (fromIntegral x / fromIntegral fact))
You've said that fact = findAFact x, which has type Integral x => x, but you're using it in a division with /, so it thinks it needs to satisfy both Integral and RealFrac.
What would actually be better is to just use div instead (I've also cleaned up the code a little bit so that it's easier to read and you aren't shadowing an existing binding for x):
completeFacts :: Integral x => x -> [x]
completeFacts x = tryForFact [] x
where
tryForFact fs 1 = fs
tryForFact fs y = let fact = findAFact y
in tryForFact (fact:fs) (y `div` fact)
The floor and / functions are what tripped you up.
(floor ((fromIntegral x) / fact))
Try using div instead.
fromIntegral x `div` fact

Resources