Haskell type class error - haskell

I can't figure it out, Code:
smallSum :: (Ord a, Integral a) => a -> a
smallSum n
| n < 0 = 0
| (n < 20) = n + smallSum (n - 1)
| otherwise = error "Number needs to be in 1..10"
fastSumOfSeriesLength :: (Ord a, Integral a) => a -> a
fastSumOfSeriesLength x
| x < 10 = smallSum x
| x >= 10 = sum (take (rest - 1) [dif !! (firstDigit - 1), dif !! (firstDigit - 1) + 100..]) + smallList !! (firstDigit - 1)
where
smallList = [smallSum x | x <- [1..10]]
largeList = [smallSum x | x <- [11..20]]
dif = [l - s | l <- largeList, s <- smallList]
firstDigit = x `mod` 10
rest = x `div` 10
Error:
ghci> :r
[1 of 1] Compiling Main ( learn.hs, interpreted )
learn.hs:194:32:
Could not deduce (a ~ Int)
from the context (Ord a, Integral a)
bound by the type signature for
fastSumOfSeriesLength :: (Ord a, Integral a) => a -> a
at learn.hs:191:26-54
`a' is a rigid type variable bound by
the type signature for
fastSumOfSeriesLength :: (Ord a, Integral a) => a -> a
at learn.hs:191:26
In the first argument of `(-)', namely `rest'
In the first argument of `take', namely `(rest - 1)'
In the first argument of `sum', namely
`(take
(rest - 1)
[dif !! (firstDigit - 1), dif !! (firstDigit - 1) + 100 .. ])'
Failed, modules loaded: none.
Im looking for someone to point out whats wrong, what it would look light working and what I need to google to learn more about this error.

Check out the types of (!!) and take:
*Main> :t (!!)
(!!) :: [a] -> Int -> a
*Main> :t take
take :: Int -> [a] -> [a]
Since you use these on expressions with the same type as x, this means x must be an Int -- but you declared that this function should work on any kind of (integral) number. (If you read the error slowly, hopefully you will be able to see it saying this.) The simplest fix is to import Data.List and use genericIndex and genericTake instead.

Related

Trying to find GCD with Haskell. Where is the error in my code?

As an exercise, I'm trying to write this by myself but I'm stuck and don't know where the error is in my code.
module Hf where
--sumSquaresTo :: Integer -> Integer
--sumSquaresTo x = sum [ n^2 | n <- [1..x] ]
divides a b = b `mod` a == 0
divisors a = [n | n <- [1..a], n `divides` a ]
lnko :: Integer -> Integer -> Integer
lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
GHCI output:
error:
* Couldn't match expected type `Integer'
with actual type `[a0 -> a0]'
* In the expression:
[n | n <- [1 .. max (a b)], (n `divides` a) && (n `divides` b)]
In an equation for `lnko':
lnko a b
= [n | n <- [1 .. max (a b)], (n `divides` a) && (n `divides` b)]
|
12 | lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error:
* Couldn't match expected type `Integer -> a0'
with actual type `Integer'
* The function `a' is applied to one argument,
but its type `Integer' has none
In the first argument of `max', namely `(a b)'
In the expression: max (a b)
|
12 | lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
| ^^^
error:
* Couldn't match expected type `a0 -> a0'
with actual type `Integer'
* In the second argument of `divides', namely `a'
In the first argument of `(&&)', namely `(n `divides` a)'
In the expression: (n `divides` a) && (n `divides` b)
* Relevant bindings include
n :: a0 -> a0
(bound at C:\\Users\erdos\Desktop\haskell\hazi1.hs:12:17)
|
12 | lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
| ^
error:
* Couldn't match expected type `a0 -> a0'
with actual type `Integer'
* In the second argument of `divides', namely `b'
In the second argument of `(&&)', namely `(n `divides` b)'
In the expression: (n `divides` a) && (n `divides` b)
* Relevant bindings include
n :: a0 -> a0
(bound at C:\\Users\erdos\Desktop\haskell\hazi1.hs:12:17)
|
12 | lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
| ^
Failed, no modules loaded.
Well, there are 2 mistakes.
In Haskell, you do not write max(a b), but simply max a b. This is called currying.
Your function actually locates all common factors. For instance:
λ lnko 8 16
[1,2,4,8]
If you amend the type signature accordingly, it will work. Or you may select one of the factors somehow.
Overall, this is great code. Keep going!
The types do not match. Indeed, in your function:
lnko :: Integer -> Integer -> Integer
lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
You here return a list, since you use list comprehension. Furthermore you made some syntactical errors. For example max (a b) means that you perform a function application with a as function, and b as parameter. This should be max a b.
You can rewrite this to:
lnko :: Integer -> Integer -> Integer
lnko a b = maximum [n | n <- [1..min a b], n `divides` a, n `divides` b ]
But nevertheless, you here use a method where you iterate over all possible dividers, to find the largest one. You can for example use the Euclidean algorithm [wiki] which will usually outperform linear search:
lnko :: Integral i => i -> i -> i
lnko a 0 = a
lnko a b = lnko b (mod a b)
This will be more safe as well, for example if you use negative numbers in the parameters.

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.)

Why did the Haskell typesystem fail to catch this?

The following compiles without warning or error.
factors n = [x | x<-[1..n], n `mod` x == 0]
perfects n = [x | x <- [1..n], x == sum (factors (init x))]
main = putStrLn "hello"
Even though I made a mistake in it.
perfects n = [x | x <- [1..n], x == sum (factors (init x))] -- incorrect
perfects n = [x | x <- [1..n], x == sum (init (factors x))] -- should have been
Where is the static type checking to rescue?
The reason I think it should have caught the mistake is:
factor clearly expects an Integral since its argument is used with mod, while init returns a List
not to mention that x is drawn from a List of Integers and init expects a List
If you look at the type ghc has deduced for it you can see
perfects :: forall a. (Eq a, Integral [a]) => [a] -> [[a]]
So if you have an instance that makes lists be in class Integral it works.
And ghc doesn't know that's not what you intend.
You'll get an error if you put the intended type signature on perfects, or of you use perfects in the way you intended (change main to print (perfects 42)).
EDIT This makes your code do something (nonsensical):
module Main where
factors n = [x | x<-[1..n], n `mod` x == 0]
perfects n = [x | x <- [1..n], x == sum (factors (init x))]
instance Num [a]
instance Integral a => Integral [a]
instance Real a => Real [a]
instance Enum [a] where
enumFromTo _ _ = []
main = print (perfects 5)
So what you wrote could be what you intended. This is why it's good to always write type signatures, so that the compiler can see what you had in mind. Or at least, you should check that the inferred type is what you intended.
What augustss said, but I'll add some thoughts.
The issue (not problem!) here is that Haskell makes a tradeoff: more flexibility, at the cost of concrete error reporting. Since Haskell just allows many more things, there are a lot of situations where, compared to more mainstream languages, it either can't report an error, or the error it reports is more abstract than such other languages would report.
For example, suppose you meant to type 1 + 2, but you fat fingered and typed 1 0 2. Here's how Python responds:
Python 2.7.2 (default, Oct 11 2012, 20:14:37)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 0 2
File "<stdin>", line 1
1 0 2
^
SyntaxError: invalid syntax
Simple: "you typed something wrong." Now Haskell:
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> 1 0 2
<interactive>:2:1:
No instance for (Num (a0 -> a1 -> t0)) arising from the literal `1'
Possible fix:
add an instance declaration for (Num (a0 -> a1 -> t0))
In the expression: 1
In the expression: 1 0 2
In an equation for `it': it = 1 0 2
<interactive>:2:3:
No instance for (Num a0) arising from the literal `0'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Num Double -- Defined in `GHC.Float'
instance Num Float -- Defined in `GHC.Float'
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus three others
In the first argument of `1', namely `0'
In the expression: 1 0 2
In an equation for `it': it = 1 0 2
<interactive>:2:5:
No instance for (Num a1) arising from the literal `2'
The type variable `a1' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Num Double -- Defined in `GHC.Float'
instance Num Float -- Defined in `GHC.Float'
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus three others
In the second argument of `1', namely `2'
In the expression: 1 0 2
In an equation for `it': it = 1 0 2
In Python, 1 0 2 is a syntax error. In Haskell, 1 0 2 means apply the function 1 to the arguments 0 and 2. Haskell's error message isn't "you can't do that," but rather, "you haven't told me how to coerce a number to a two-argument function" (no instance for Num (a0 -> a1 -> t0)).
In your case, you managed to write something that Haskell knows how to interpret, but means something very different from what you meant. The best thing to do here, as a programmer, is to use top-level type declarations that describe your intent, and then the compiler can check against those.
Final note: keep in mind that you can do this in Haskell:
-- | Treat lists of numbers as numbers. Example:
--
-- >>> [1..3] * [2..5]
-- [2,3,4,5,4,6,8,10,6,9,12,15]
--
instance Num a => Num [a] where
xs + ys = [x + y | x <- xs, y <- ys]
xs * ys = [x * y | x <- xs, y <- ys]
xs - ys = [x - y | x <- xs, y <- ys]
negate xs = map negate xs
abs xs = map abs xs
signum xs = map signum xs
fromInteger x = [fromInteger x]
-- | Treat functions as numbers if they return numbers. The functions
-- must have the same argument type. Example:
--
-- >>> 1 0 2
-- 1
instance Num a => Num (r -> a) where
f + g = \r -> f r + g r
f * g = \r -> f r * g r
f - g = \r -> f r - g r
negate f = negate . f
abs f = abs . f
signum f = signum . f
fromInteger x = const (fromInteger x)
Same thing can be done with the Integral class.

Haskell: What is the difference between (+1) and (\x->x+1)?

Is there a difference between these two functions?
ghct says:
Prelude> :t (+1)
(+1) :: Num a => a -> a
Prelude> :t \x->x+1
\x->x+1 :: Num a => a -> a
But
When I used (+1) syntax in this piece of code:
data B = B {
pos :: Int,
cells :: [Int]
} deriving (Show)
createB :: Int -> B
createB n = B 0 (take n $ repeat 0)
size :: B -> Int
size b = length $ cells b
get_curr :: B -> Int
get_curr b = (cells b) !! (pos b)
apply :: (Int -> Int) -> B -> B
apply f b = let n = pos b
h = take n $ cells b -- head
t = drop (n + 1) $ cells b -- tail
in B n $ h ++ [f (get_curr b)] ++ t
-- ...
eval :: [Char] -> StateT B IO ()
eval [] = return ()
eval (x:xs) = do
b <- get
put $ case x of
'+' -> apply (+1) b
'-' -> apply (-1) b
'>' -> fwd b
'<' -> back b
otherwise -> b
-- ...
prelude (as well as compiler) said:
> :load BrainFuck.hs
[1 of 1] Compiling BrainFuck ( BrainFuck.hs, interpreted )
BrainFuck.hs:49:40:
No instance for (Num (Int -> Int))
arising from the literal `1'
Possible fix: add an instance declaration for (Num (Int -> Int))
In the expression: 1
In the first argument of `apply', namely `(- 1)'
In the expression: apply (- 1) b
Failed, modules loaded: none.
What am I doing wrong?
sorry if code is not-so-cool (full source here: https://github.com/nskeip/bf/blob/a755b2d27292593d63fe1e63c2a6e01cebc73520/BrainFuck.hs)
This code:
(-1)
... doesn't mean the same thing as this code:
\ x -> x - 1
- is a special case in Haskell; it is the only prefix operator in the language. When you write (-1), you get "negative one" which is a number, and not "subtract one" which is a function.
You should use subtract 1 to get what you need.
Your problem is not with (+1), it's with (-1):
Prelude> :t (-1)
(-1) :: Num a => a
-1 is a number! Try with apply (\x -> x-1) b or apply (subtract 1) b.
There is no difference between (+1) and \x -> x + 1 and if you look closely, (+1) isn't what's causing your error. (-1) is. And that's because unlike (+1), (-1) is not an operator section, it's negative one.
Instead of subtract the decrement expression can be written directly also as (+(-1)) .

Resources