I'm new to haskell.
Got a parse error and dont know what is wrong.
fromDecTo :: (Int -> Int) -> [Int]
fromDecTo (n x) | (n < x) = [n]
| otherwise = fromDecTo (n `div` x) ++ [n `mod` x]
This should convert a decimal number into a number with base x (a.e. hexadecimal).
Please help me.
fromDecTo :: (Int -> Int) -> [Int]
This is a function having one argument, a function from integers to integers. This is not what you want: you want a function having two arguments, i.e.
fromDecTo :: Int -> Int -> [Int]
Similarly, the pattern
fromDecTo (n x)
expresses the result of applying a function n to x and then applying fromDecToto the result. This is not what you want, taking two arguments is done with
fromDecTo n x
As a final note, even if it not customary to do so, it is possible to add parentheses, but with the opposite association. The same type shown above could be written
fromDecTo :: Int -> (Int -> Int)
which stresses the fact that functions are curried in Haskell: a binary function is actually a function taking only one argument, the first, and returning a function taking one other argument, the second, and finally returning the result.
Similarly, instead of
fromDecTo n x
we could write
(fromDecTo n) x
since n is applied to fromDecTo first, and then x after that.
You have several issues in your code. Here is what you want to achieve:
fromDecTo :: Int -> Int -> [Int]
fromDecTo n x | (n < x) = [n]
| otherwise = fromDecTo (n `div` x) x ++ [n `mod` x]
Related
I am new to Haskell and I am struggling to get this concept to work.
I have to use a list of integers as a parameter and count the number of perfect squares (1,4,9,etc) in the list and output that value. So for example, if I entered myfunction[1,5,9] the output would be 2.
So far I have only got one function to work:
myfunction list = map per list
where per y = floor(sqrt (y) * sqrt (y))
Takes the square root of the element multiplied by the square root of the element. My mindset with the above is that I could set the above result equal to the original element. And if they are equal to each other, that would mean they are perfect squares. And then I would increment a value.
My issue is that my book doesn't give me any ideas for how to increment a variable or how to incorporate more than 1 function at a time. And as a result, I've been aimlessly working on this over the course of 3 days.
Thank you in advance for any help, advice, or resources!
fixing your version
first completed your version could look like this:
myfunction list = length $ filter per list
where
per y = floor(sqrt y * sqrt y) == y
this would even type-check but it would not work (try it)
that's because there is a small little problem - let's make it obvious by giving some types:
myfunction :: [Int] -> Int
myfunction list = length $ filter per list
where
per :: Int -> Bool
per y = floor(sqrt y * sqrt y) == y
you get an error:
No instance for (Floating Int) arising from a use of ‘sqrt’
it is trying to say to you that it does not know how to use sqrt for an Int - an easy fix is using fromIntegral and let it convert the Int into something that can:
myfunction :: [Int] -> Int
myfunction list = length $ filter per list
where
per :: Int -> Bool
per y = floor(sqrt (fromIntegral y) * sqrt (fromIntegral y)) == y
this kind of works (wrong answer) but gives an warning - we could get rid of with
myfunction :: [Int] -> Int
myfunction list = length $ filter per list
where
per :: Int -> Bool
per y = floor(sqrt (fromIntegral y :: Double) * sqrt (fromIntegral y)) == y
were we tell Haskell what type to use for the conversion (the warning would tell you that you default to this anyway).
So there is the wrong answer still.
#jpmarinier already told why - the way you test/sqr is sadly not cutting it (at least as I thought you wanted) - here is a fix:
myfunction :: [Int] -> Int
myfunction list = length $ filter per list
where
per :: Int -> Bool
per y = let y' = (fromIntegral y :: Double) in sqrt y' ** 2 == y'
where we first convert y to a Double value y' and test this.
Another option is using a integer-sqr as #jpmarinier mentioned:
myfunction :: [Int] -> Int
myfunction list = length $ filter per list
where
per :: Int -> Bool
per y = squareRoot y * squareRoot y == y
squareRoot :: Int -> Int
squareRoot = floor . sqrt . (fromIntegral :: Int -> Double)
that should finally work.
without floor and sqr:
ok this is maybe a bit to grok for you but here is how you can do this by sieving out the values.
Let's start by creating a (ascending) list of all perfect squares - I don't know which type you want those numbers to be so let's stay generic as well:
-- need later
import Data.List (sort)
perfectSquares :: Enum a => Num a => [a]
perfectSquares = [ n*n | n <- [1..] ]
no let's make a function counting elements from two lists - if the lists are sorted this can be done recursively by walking alongside the lists - I don't know if your input lists are always sorted so let's sort it before:
countOccurances :: (Enum a, Num a, Ord a) => [a] -> [a] -> a
countOccurances from list =
countAlong from $ sort list
where
countAlong [] _ = 0
countAlong _ [] = 0
countAlong allXs#(x:xs) allYs#(y:ys)
| x < y = countAlong xs allYs
| x > y = countAlong allXs ys
| otherwise = 1 + countAlong allXs ys
having both we can combine them for the answer:
import Data.List (sort)
countPerfectSquares :: (Enum a, Num a, Ord a) => [a] -> a
countPerfectSquares = countOccurances perfectSquares
countOccurances :: (Enum a, Num a, Ord a) => [a] -> [a] -> a
countOccurances from list =
countAlong from $ sort list
where
countAlong [] _ = 0
countAlong _ [] = 0
countAlong allXs#(x:xs) allYs#(y:ys)
| x < y = countAlong xs allYs
| x > y = countAlong allXs ys
| otherwise = 1 + countAlong allXs ys
perfectSquares :: Enum a => Num a => [a]
perfectSquares = [ n*n | n <- [1..] ]
Example:
> countPerfectSquares [1,5,9] :: Int
2
I'm trying to do a function that given an operator and a function will go through a list like such:
reduce (*) even [1,2,3,4,5] => 8
reduce (+) odd [1,2,3,4,5] => 9
At first I had something like this:
reduce :: (Int-> Int-> Int) -> (Int->Bool) -> [Int] -> Int
reduce op x y = foldl op 1 (filter x y)
and it worked fine for multiplying, but added one number when trying to do a sum. So I thought of adding an if:
reduce :: (Int-> Int-> Int) -> (Int->Bool) -> [Int] -> Int
reduce op x y =
if op == (*) then foldl op 1 (filter x y)
else if op == (+) then foldl op 0 (filter x y)
else 0
However when I do this I get the following error:
Instance of Eq (Int -> Int -> Int) required for definition of reduce
What does it mean exactly? Any ideas? Thanks in advance
It means that with your current imports you cannot compare functions for equality (and even with suitable imports, there is no really good way to do the equality you ask for).
One simple solution is to demand that the user provide both the operation and the unit, thus:
reduce op u x y = foldl op u (filter x y)
In many cases of interest, there is already a Monoid instance that specifies the operator and unit. For example, there are the Sum and Product instances, so you might consider writing
reduce inject p = foldMap inject . filter p
which would be used like this:
> reduce Sum even [1..5]
Sum {getSum = 6}
> reduce Product odd [1..5]
Product {getProduct = 15}
What does it mean exactly? Any ideas? Thanks in advance
You're trying to compare some (Int -> Int -> Int) to another one. But functions cannot get checked on equality. Provide the initial value instead:
reduce :: (Int -> Int -> Int) -> (Int -> Bool) -> Int -> [Int] -> Int
reduce op f x xs = foldl op x (filter f xs)
By the way, you can generalize your function's type:
reduce :: (b -> a -> b) -> (a -> Bool) -> b -> [a] -> a
reduce op f x xs = foldl op x (filter f xs)
Alternatively, use a monoid and foldMap.
I want to check if an Integral is a square:
isSquare :: Integral n => n -> Bool
isSquare n = (>1) $ length (filter (\x -> n / x == x) numList)
where numList = reverse [1..n]
Apart from whether or not iterating through a list is the right approach here, when I try to compile this function I get the error:
No instance for (Fractional Int) arising from a use of ‘/’
My understanding of this is that since I am binding n to the Integral type, by dividing it I am breaking the function's rigid type construction. How can I fix my function so that it compiles?
You could add fromIntegral to everything to get Fractionals:
filter (\x -> fromIntegral n / fromIntegral x == fromIntegral x) numList
Or just square the number instead:
filter (\x -> n == x ^ 2)
Also, your length check shouldn’t be >1. ==1 would make more sense, but you should use null to avoid having to try every number every time (besides using a faster algorithm in the first place).
isSquare :: Integral a => a -> Bool
isSquare n = not $ null $ filter (\x -> n == x ^ 2) numList
where numList = [n,n-1..1]
halveEvens :: [Int] -> [Int]
halveEvens xs = [if xs == even then 'div' 2 xs | x<-xs]
Hey I'm trying to write down some code in haskell which will take the evens from a list and divide them by two. I am really new to this, so I am having some trouble. Is there anyone who could put me on the right track? I want to achieve this using list comprehension!
In your function xs is a list, even is a function that checks if Integral is even.
To use functions like operators, you enclose it in back quotes like this : x `div` 2.
halveEvens :: [Int] -> [Int]
halveEvens = map halveOneEven
halveOneEven :: Int -> Int
halveOneEven x = if (even x) then (x `div` 2) else x
Using list comprehension with a guard after a comma:
halveEvens xs = [x `div` 2 | x<-xs, even x]
You could read it as a mathematical definition: take all x values from xs that are even, and collect the result of dividing them into a list. In ghci you can use :t to check the types and make them match (xs is of type [Int], x is Int, and even is (Integral a) => a -> Bool).
-- 3 (find k"th element of a list)
element_at xs x = xs !! x
prop_3a xs x = (x < length xs && x >= 0) ==> element_at xs (x::Int) == (xs !! x::Int)
When prop_3a is ran through QuickCheck, it gives up, because it won't generate long enough lists.
How can I write a generator that will generate lists with length longer than the random integer?
hammar's answer is perfectly adequate for the problem. But for the sake of answering the precise question asked, I couldn't help but investigate a bit. Let's use forAll.
prop_bang x = x >= 0 ==> forAll (listLongerThan x) $ \xs ->
element_at xs x == xs !! x
So now we need a function, listLongerThan :: Int -> Gen [Int]. It takes a length, x, and produces a generator which will produce lists of length greater than x.
listLongerThan :: Int -> Gen [Int]
listLongerThan x = replicateM (x+1) arbitrary
It's rather straightforward: we simply take advantage of the Monad instance of Gen. If you run quickCheck prop_bang, you'll notice it starts taking quite a long time, because it begins testing absurdly long lists. Let's limit the length of the list, to make it go a bit faster. Also, right now listLongerThan only generates a list that is exactly x+1 long; let's mix that up a bit, again utilizing the Monad instance of Gen.
prop_bang =
forAll smallNumber $ \x ->
forAll (listLongerThan x) $ \xs ->
element_at xs x == xs !! x
smallNumber :: Gen Int
smallNumber = fmap ((`mod` 100) . abs) arbitrary
listLongerThan :: Int -> Gen [Int]
listLongerThan x = do
y <- fmap (+1) smallNumber -- y > 0
replicateM (x+y) arbitrary
You can use sample smallNumber or sample (listLongerThan 3) in ghci to make sure it is generating the correct stuff.
How about going the other way? First we let QuickCheck pick a list and then we constrain what indices we allow. This works, and does not throw away any test cases.
prop_3a (NonEmpty xs) = forAll (choose (0, length xs - 1)) $ \i ->
element_at xs i == (xs !! i :: Int)
Here, I use forAll to use a specific generator for the indices, in this case using choose which picks an element from a specified range, and I also use the NonEmptyList type to ensure that we don't try to index into an empty list.
This works:
import Test.QuickCheck
element_at :: [a] -> Int -> a
element_at xs i = xs !! i
prop_3a :: [Int] -> Int -> Property
prop_3a xs i = (i >= 0) ==> (length xs > i) ==> element_at xs i == xs !! i
However, the problem with this is that a lot of sample values are discarded. You could use things like Positive to help with ensuring that the index is valid.
If you want to be more complex, you can use more newtype wrappers to try and generate values of sufficient length (possibly using sized, or generate the list and the index together: generate the list, and then generate the index based upon the length of the list).