So I just started learning Haskell and I have been stuck on this for quite some time already. So I have a function that calculates a number after an offset has been minus (minimum value is 0). I managed to do this function with the types explicitly shown.
offSetter :: Int -> Int -> Int
offSetter number offset
| number - offset >= 0 = number - offset
| otherwise = 0
But when I tried to change it to use generic types as below, it keeps giving me an error. Am I doing it wrong?
offSetter :: Num a => a -> a -> a
offSetter number offset
| number - offset >= 0 = number - offset
| otherwise = 0
The error I'm getting:
* Could not deduce (Ord a) arising from a use of '>='
from the context: Num a
bound by the type signature for:
offSetter :: forall a. Num a => a -> a -> a
at src\test.hs:57:1-33
Possible fix:
add (Ord a) to the context of
the type signature for:
offSetter :: forall a. Num a => a -> a -> a
* In the expression: number - offset >= 0
In a stmt of a pattern guard for
an equation for `offSetter':
number - offset >= 0
Solved it by adding Ord a:
offSetter :: (Num a, Ord a) => a -> a -> a
offSetter number1 offSet
| number1 - offSet >= 0 = number1 - offSet
| otherwise = 0
As you discovered, you need to add the type class Ord as a constraint to the type a with the following type signature:
offSetter :: (Num a, Ord a) => a -> a -> a
This is because Ord is the typeclass with comparison operators like (>=).
So Ord is used because there are elements like Strings that is not applicable to Num?
No, since String is not a member of the Num typeclass, the original declaration already excludes it as a possible candidate for the type a. As I stated earlier, you need to use Ord in order to guarantee that the type a has the operator (>=) available.
Related
This question already has answers here:
`String' is applied to too many type arguments
(2 answers)
Closed 4 years ago.
--Find kth element of list
elementAt :: (Int b) => [a] -> b -> a
elementAt a b = case a of [] -> error "Empty List"
a -> if (length a) <= b && b>=1 then a !! (b- 1) else error "Wrong index"
Gives an error Expected kind -> constraint but Int has kind *.
Compared to:
elementAt :: [a] -> Int -> a
elementAt a b = case a of [] -> error "Empty List"
a -> if (length a) <= b && b>=1 then a !! (b- 1) else error "Wrong index"
Which doesn't give an error.
Why is that ?
Int is a type, not a type class, so Int b is not a valid constraint. What constraint do you need on b?
You use b with both <= and >=, so b has to have an Ord constraint.
You use b - 1, so b has to have a Num constraint.
However, since b-1 is the second argument to (!!) :: [a] -> Int -> a, you don't really have any leeway in what type b can be: b - 1 has to be an Int, and so does b. Thus, the type should simply be
elementAt :: [a] -> Int -> a
Since Int has both Num and Ord instances, the requirements listed above are satisfied.
This is the code I have which results in the error that follows:
import Prelude hiding (div)
data Expr = Expr Op Int Int deriving (Show)
data Op = Add | Sub | Mul | Div deriving (Show)
evaluate :: (Num a) => Expr -> a
evaluate (Expr Add a b) = a + b
--evaluate (Expr Sub a b) = sub a b
--evaluate (Expr Mul a b) = mul a b
--evaluate (Expr Div a b) = div a b
Error message:
exprs.hs:8:27: error:
• Couldn't match expected type ‘a’ with actual type ‘Int’
‘a’ is a rigid type variable bound by
the type signature for:
evaluate :: forall a. Num a => Expr -> a
at exprs.hs:7:1-32
• In the expression: a + b
In an equation for ‘evaluate’: evaluate (Expr Add a b) = a + b
• Relevant bindings include
evaluate :: Expr -> a (bound at exprs.hs:8:1)
|
8 | evaluate (Expr Add a b) = a + b
| ^^^^^
Failed, 0 modules loaded.
However, the (+) function has type (Num a) => a -> a -> a, and
the pattern I'm matching in the function evaluate has two Ints (a & b) which are both part of the Num typeclass. Since the result of calling (+) on a & b will be of type Int (from the Num typeclass) and that is also what I'm declaring the type of the output of my evaluate function to be, why is GHCi giving me this error?
Note that, if I change the type declaration of evaluate to
evaluate :: Expr -> Int
then this error does not come up.
evaluate :: (Num a) => Expr -> a
states that for any type a which has a Num instance, evaluate can return a value of type a given an Expr value. However given the definition of Expr, you can only ever return an Int, and the compiler is therefore rejecting your definition.
If it were allowed you would be able to do:
evaluate (Expr Add 2 3) :: Double
which your definition cannot satisfy.
You can use your definition if you allow Expr to be parameterised by the expression type:
data Expr a = Expr Op a a deriving (Show)
evaluate :: (Num a) => Expr a -> a
evaluate (Expr Add a b) = a + b
...
Im pretty much new to Haskell, so if Im missing key concept, please point it out.
Lets say we have these two functions:
fact n
| n == 0 = 1
| n > 0 = n * (fact (n - 1))
The polymorphic type for fact is (Eq t, Num t) => t -> t Because n is used in the if condition and n must be of valid type to do the == check. Therefor t must be a Number and t can be of any type within class constraint Eq t
fib n
| n == 1 = 1
| n == 2 = 1
| n > 2 = fib (n - 1) + fib (n - 2)
Then why is the polymorphic type of fib is (Eq a, Num a, Num t) => a -> t?
I don't understand, please help.
Haskell always aims to derive the most generic type signature.
Now for fact, we know that the type of the output, should be the same as the type of the input:
fact n | n == 0 = 1
| n > 0 = n * (fact (n - 1))
This is due to the last line. We use n * (fact (n-1)). So we use a multiplication (*) :: a -> a -> a. Multiplication thus takes two members of the same type and returns a member of that type. Since we multiply with n, and n is input, the output is of the same type as the input. Since we use n == 0, we know that (==) :: Eq a => a -> a -> Bool so that means that that input type should have Eq a =>, and furthermore 0 :: Num a => a. So the resulting type is fact :: (Num a, Eq a) => a -> a.
Now for fib, we see:
fib n | n == 1 = 1
| n == 2 = 1
| n > 2 = fib (n - 1) + fib (n - 2)
Now we know that for n, the type constraints are again Eq a, Num a, since we use n == 1, and (==) :: Eq a => a -> a -> Bool and 1 :: Num a => a. But the input n is never directly used in the output. Indeed, the last line has fib (n-1) + fib (n-2), but here we use n-1 and n-2 as input of a new call. So that means we can safely asume that the input type and the output type act independently. The output type, still has a type constraint: Num t: this is since we return 1 for the first two cases, and 1 :: Num t => t, and we also return the addition of two outputs: fib (n-1) + fib (n-2), so again (+) :: Num t => t -> t -> t.
The difference is that in fact, you use the argument directly in an arithmetic expression which makes up the final result:
fact n | ... = n * ...
IOW, if you write out the expanded arithmetic expression, n appears in it:
fact 3 ≡ n * (n-1) * (n-2) * 1
This fixes that the argument must have the same type as the result, because
(*) :: Num n => n -> n -> n
Not so in fib: here the actual result is only composed of literals and of sub-results. IOW, the expanded expression looks like
fib 3 ≡ (1 + 1) + 1
No n in here, so no unification between argument and result required.
Of course, in both cases you also used n to decide how this arithmetic expression looks, but for that you've just used equality comparisons with literals, whose type is not connected to the final result.
Note that you can also give fib a type-preservig signature: (Eq a, Num a, Num t) => a -> t is strictly more general than (Eq t, Num t) => t -> t. Conversely, you can make a fact that doesn't require input- and output to be the same type, by following it with a conversion function:
fact' :: (Eq a, Integral a, Num t) => a -> t
fact' = fromIntegral . fact
This doesn't make a lot of sense though, because Integer is pretty much the only type that can reliably be used in fact, but to achieve that in the above version you need to start out with Integer. Hence if anything, you should do the following:
fact'' :: (Eq t, Integral a, Num t) => a -> t
fact'' = fact . fromIntegral
This can then be used also as Int -> Integer, which is somewhat sensible.
I'd recommend to just keep the signature (Eq t, Num t) => t -> t though, and only add conversion operations where it's actually needed. Or really, what I'd recommend is to not use fact at all – this is a very expensive function that's hardly ever really useful in practice; most applications that naïvely end up with a factorial really just need something like binomial coefficients, and those can be implemented more efficiently without a factorial.
I want to be able to make operators such as found in VB(.net) like shown below
Console.WriteLine ( 16 Mod 2 )
produces an output shown below
0
As you can see, this makes code slightly easier to read. How would I go about making functions that do this?
I have tried the following format
equal :: Integer -> Integer -> bool
x `equal` y = x == y
and I get the following error
*Main> 5 equal 5
<interactive>:1:1: error:
* Non type-variable argument
in the constraint: Num ((Integer -> Integer -> Bool) -> t -> t1)
(Use FlexibleContexts to permit this)
* When checking the inferred type
it :: forall t t1.
(Num ((Integer -> Integer -> Bool) -> t -> t1), Num t) =>
t1
*Main>
What is going wrong and how do I do it correctly?
You need to use backticks around equal when you call it, exactly as you did to define it.
5 `equal` 5
The way you wrote it, Haskell thinks you're trying to pass equal as an argument to 5, rather than the other way around.
I have to derive the type of this function:
func x = map -1 x
And I've already found a way, using a tip to change it to a lambda expression:
func = \x -> (map) - (1 x)
If I express it like that, its fine and I get the same type as the original, but I'm not sure why its grouped like this. Could someone explain it?
For example, why isn't it like this:
func = \x -> (map - 1) x
or something similar.
I know it's a useless function etc. but I can't change the function, I just have to derive its type.
If you write this function in a file, eg:
test.hs has func x = map -1 x
and use :t func in the interpreter, it will reply:
func :: (Num (t -> (a -> b) -> [a] -> [b]),
Num ((a -> b) -> [a] -> [b])) =>
t -> (a -> b) -> [a] -> [b]
I now believe you meant to ask why
func x = map -1 x
has the type (Num (t -> (a -> b) -> [a] -> [b]), Num ((a -> b) -> [a] -> [b])) => t -> (a -> b) -> [a] -> [b], and how you can bracket the expression to make it have that type.
First, you have to recognise that the space is an operator in haskell, and has the highest precedence of all.
Let's use # instead of space, with highest precedence we can:
infixl 9 #
f # x = f x
We can replace and space without an operator with #:
func x = map - 1 # x
because the space between 1 and x was the only one without an operator (- is between map and 1).
Since # has higher precedence than -, we get
func x = map - (1 # x)
or equivalently
func x = map - (1 x)
Another example
func2 x = map (-1) x
> :t func2
func2 :: Num (a -> b) => [a] -> [b]
This translates as
func2' x = map # (-1) # x
but why isn't there a # between the - and the 1? In this case, - in front of a numeric literal like 1 means negate:
> (-1)
-1
> (negate 1)
-1
> (subtract 1)
<interactive>:73:1:
No instance for (Show (a0 -> a0))
arising from a use of `print'
Possible fix: add an instance declaration for (Show (a0 -> a0))
In a stmt of an interactive GHCi command: print it
So this function is trying to map the negative of 1 over a list. For that to work, it would need negative 1 to be a function, which is why it needs a numeric instance for functions (the Num (a->b) => at the start of the type).
but i'm not sure why its grouped like this. Could someone explain it? In example, why its not like that:
func = \x -> (map - 1) x
Precedence. The language definition specifies that the precedence of (prefix) function application is higher than that of any infix operator, so
map -1 x
is parsed as the application of the infix operator (-) to the two operands map and 1 x, like 3 + 4 * 5 is parsed 3 + (4 * 5) due to the higher precedence of (*) compared to that of (+).
Although the interpreter has assigned a type to the expression, it's not a sensible one. Let's see what the function should be
func x = map -1 x
looks like we want to bracket that like this
func x = map (-1) x
in the hope that it subtracts one from each element of a list, but unfortunately, the - is considered to be negation when it's in front of a numeric literal, so we need to bracket it to change it into the subtraction function:
func x = map ((-) 1) x
Now this function subtracts each number in the list from 1:
func [1,2,3]
=[(-) 1 1, (-) 1 2, (-) 1 3]
=[ 1-1, 1-2, 1-3]
=[ 0, -1, -2]
The type is
func :: Num a => [a] -> [a]
If you wanted to subtract one from each element of the list, rather than subtracting each element of the list from 1, you could use func x = map (subtract 1) x. As hammar points out, the subtract function exists exactly for the purpose of allowing this.
Your alternative
func = \x -> (map - 1) x
This can't work because (-) has type Num a => a -> a -> a, whereas map has type (a -> b) -> [a] -> [b]. You can't subtract one from a function, because a function isn't a numeric value.