I am trying to implement the law of cosines function, and here is my code:
cosC :: [a] -> a
cosC sides
| length sides < 3 = 0
| otherwise = (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
where x = head(tail(tail(sides)))
y = head(tail(sides))
z = head(sides)
But I get two errors:
No instance for (Fractional a)
arising from a use of `/'
In the expression: (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
In an equation for `cosC':
cosC sides
| length sides < 3 = 0
| otherwise = (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
where
x = head (tail (tail (sides)))
y = head (tail (sides))
z = head (sides)
and
No instance for (Num a)
arising from the literal `2'
In the first argument of `(*)', namely `2'
In the first argument of `(*)', namely `2 * x'
In the second argument of `(/)', namely `(2 * x * y)'
Edit: I have fixed the sign typo in the law of cosines above. Thanks to Daniel Fischer for pointing that out.
You're trying to calculate numerical results out of general types a, that can't possibly work. (It's like trying to build a bridge not just for general road-vehicles but for general things, e.g. spaceships, skyscrapers, paper clips and neutron stars). Just add the Floating constraint to a:
cosC :: Floating a => [a] -> a
and you can perform any of the arithmetic operations you need for such a calculation. (Fractional is actually enough for this function, but you won't be able to calculate the arccos of the result then).
Unrelated to your problem, note that there's a much better way to decompose lists in Haskell:
cosC (x:y:z:_) = (x^2 + y^2 - z^2) / (2*x*y)
cosC _ = 0
is equivalent to your definition. Why are you taking the arguments as a list anyway? That's quite a Lisp-ish thing to do, in Haskell I'd prefer
cosC :: Floating a => a -> a -> a -> a
cosC x y z = (x^2 + y^2 - z^2) / (2*x*y)
cosC :: Fractional a => [a] -> a
And this is how you can find out (in ghci):
*Main> let fun [x, y, z] = (x * x + y * y + z * z) / (2 * x * y)
*Main> :type fun
fun :: Fractional a => [a] -> a
Related
I want to realize power function for my custom data type. I mean power (^) which has following signature:
(^) :: (Num a, Integral b) => a -> b -> a
And I mean that my data type MyData should be instance of Num, so I could write
x :: MyData
...
y = x ^ b
where b is some Integral. It's very easy when we need function of one class like
(+), (-), (*) :: (Num a) => a -> a -> a
We just write
instance Num MyData where
(*) x y = someFunc x y
But I have no idea how to define it taking into account that there is also Integral b. That syntax should be like
instance (Integral b) => Num MyData b where
(^) x y = someFunc x y
But I've tried a hundred of such variations and nothing works. Hours of googling also didn't help.
You don't have to do anything to define (^) for your data type; if your type has a Num instance, you get x ^ b for free, because (^) is defined for any type with a Num instance. (It basically just calls * a lot.)
Note that (^) is not a member of Num or Integral; it's just a standalone function whose type is constrained by both classes.
From https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Real.html#%5E
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = f x0 y0
where -- f : x0 ^ y0 = x ^ y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-- g : x0 ^ y0 = (x ^ y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) (y `quot` 2) (x * z) -- See Note [Half of y - 1]
x0 is your MyData value; the only thing (^) ever does with x0 (by virtue of it being passed as the x argument to f or g) is to multiply it by itself, so technically (^) will work as long as you have defined (*) in your Num instance.
I'm starting to learn Haskell so I need to understand currying also (it's the first time I've seen this technique too). I think I get how it works in some cases where the currification only "eliminates" one of the parameters. Like in the next example where I'm trying to calculate the product of 4 numbers.
This is the uncurried function:
prod :: Integer->Integer->Integer->Integer->Integer
prod x y z t = x * y * z * t
This is the curried function:
prod' :: Integer->Integer->Integer->Integer->Integer
prod' x y z = (*) (x*y*z)
But I don't understand how could I continue this dynamic and do for example the same function with only two arguments and so on:
prod'' :: Integer->Integer->Integer->Integer->Integer
prod'' x y =
This is the uncurried function:
prod :: Integer -> Integer -> Integer -> Integer -> Integer
prod x y z t = x * y * z * t
This is already a curried function. In fact all functions in Haskell are automatically curried. Indeed, you here wrote a function that looks like:
prod :: Integer -> (Integer -> (Integer -> (Integer -> Integer)))
Haskell will thus produce a function that looks like:
prod :: Integer -> (Integer -> (Integer -> (Integer -> Integer)))
prod = \x -> (\y -> (\z -> (\t -> x * y * z * t)))
Indeed, we can for example generate such function:
prod2 = prod 2
This will have type:
prod2 :: Integer -> (Integer -> (Integer -> Integer))
prod2 = prod 2
and we can continue with:
prod2_4 :: Integer -> (Integer -> Integer)
prod2_4 = prod2 4
and eventually:
prod2_4_6 :: Integer -> Integer
prod2_4_6 = prod2_4 6
EDIT
The function prod' with:
prod'' x y = (*) ((*) (x*y))
Since that means you multiply (*) (x*y) with the next parameter. But (*) (x*y) is a function. You can only multiply numbers. Strictly speaking you can make functions numbers. But the Haskell compiler thus complains that:
Prelude> prod'' x y = (*) ((*) (x*y))
<interactive>:1:1: error:
• Non type-variable argument in the constraint: Num (a -> a)
(Use FlexibleContexts to permit this)
• When checking the inferred type
prod'' :: forall a.
(Num (a -> a), Num a) =>
a -> a -> (a -> a) -> a -> a
It thus says that you here aim to perform an operation with a function a -> a as first operand, but that this function is not an instance of the Num typeclass.
What you have is
prod x y z t = x * y * z * t
= (x * y * z) * t
= (*) (x * y * z) t
Hence by eta reduction (where we replace foo x = bar x with foo = bar)
prod x y z = (*) (x * y * z)
= (*) ( (x * y) * z )
= (*) ( (*) (x * y) z )
= ((*) . (*) (x * y)) z
so that by eta reduction again,
prod x y = (*) . (*) (x * y)
Here (.) is the function composition operator, defined as
(f . g) x = f (g x)
What you're asking about is known as point-free style. "Point-free" means "without explicitly mentioning the [implied] arguments" ("point" is a mathematician's jargon for "argument" here).
"Currying" is an orthogonal issue, although Haskell being a curried language makes such definitions -- and partial application ones, shown in Willem's answer -- easier to write. "Currying" means functions take their arguments one at a time, so it is easy to partially apply a function to a value.
We can continue the process of pulling the last argument out so it can be eliminated by eta reduction further. But it usually rapidly leads to more and more obfuscated code, like prod = ((((*) .) . (*)) .) . (*).
That's because written code is a one-dimensional encoding of an inherently two-dimensional (or even higher-dimensional) computational graph structure,
prod =
/
*
/ \
*
/ \
<-- *
\
You can experiment with it here. E.g., if (*) were right-associative, we'd get even more convoluted code
\x y z t -> x * (y * (z * t))
==
(. ((. (*)) . (.) . (*))) . (.) . (.) . (*)
representing just as clear-looking, just slightly rearranged, graph structure
/
<-- *
\ /
*
\ /
*
\
I'm attempting to do problem 9 of Project Euler right now, but Haskell won't stop yelling at me about types not matching up. The thing is, ghci is telling me it is expecting types different than those given in the function type definitions.
Here is the code:
solvePyth :: Int -> Int -> Float
solvePyth x y
|valid = x * y * z
|otherwise = if y < x then solvePyth x (y + 1) else solvePyth (x + 1) 1
where z = sqrt $ fromIntegral $ x^2 + y^2
valid = (x^2 + y^2 == z^2) && (x + y + z == 1000)
and here are the errors I am getting:
Prelude> :l debug
[1 of 1] Compiling Main ( debug.hs, interpreted )
debug.hs:3:14:
Couldn't match expected type `Float' with actual type `Int'
In the first argument of `(*)', namely `x'
In the first argument of `(*)', namely `x * y'
debug.hs:3:18:
Couldn't match expected type `Float' with actual type `Int'
In the second argument of `(*)', namely `y'
In the first argument of `(*)', namely `x * y'
debug.hs:6:33:
Couldn't match expected type `Int' with actual type `Float'
In the first argument of `(^)', namely `z'
In the second argument of `(==)', namely `z ^ 2'
Failed, modules loaded: none.
What I don't understand is why (*) and (^) are expecting Floats and Ints, when checking their typing in ghci with :t shows their arguements only need to be considered Nums.
Here is one way to fix the typing issue:
solvePyth :: Int -> Int -> Float
solvePyth x' y'
| valid = x * y * z
| otherwise = if y' < x' then solvePyth x' (y' + 1) else solvePyth (x' + 1) 1
where z = sqrt (x^2 + y^2)
(x, y) = (fromIntegral x', fromIntegral y')
valid = (x^2 + y^2 == z^2) && (x + y + z == 1000)
(*) and (^) will work on arguments that are installed into Num class in general, but what is important is that the type have to be the same. Here is the type definition for (*):
λ> :t (*)
(*) :: Num a => a -> a -> a
but notice that a has to be the same type, so if you partially apply Int to it:
λ> :t (* (4 :: Int))
(* (4 :: Int)) :: Int -> Int
it expects the second argument and output to be an Int as well.
On the other hand type of (^):
λ> :t (^)
(^) :: (Num a, Integral b) => a -> b -> a
works on two arguments of possibly different types, so if we partially apply an Int it will produce an Int, but the second argument can still be an arbitrary Integral:
λ> :t ((4 :: Int) ^)
((4 :: Int) ^) :: Integral b => b -> Int
Basically whenever you see a -> a -> a, it means that the type variable a eventually has to be of the same type, thats why you cannot mix Int and Float with (*), despite that they are both installed into Num.
modPow :: Int -> Int -> Int -> Int
-- Pre: 1 <= m <= sqrt(maxint)
modPow x y n
|even y = (((x^halfy) `mod` n)^2) `mod` n
|otherwise = (x `mod` n)*(x ^ (y-1) `mod` n) `mod` n
where halfy = round (y/2)
REPORT ON TERMINAL:
Recursion.hs:39:19:
No instance for (RealFrac Int) arising from a use of ‘round’
In the expression: round (y / 2)
In an equation for ‘halfy’: halfy = round (y / 2)
In an equation for ‘modPow’:
modPow x y n
| even y = (((x ^ halfy) `mod` n) ^ 2) `mod` n
| otherwise = (x `mod` n) * (x ^ (y - 1) `mod` n) `mod` n
where
halfy = round (y / 2)
Recursion.hs:39:27:
No instance for (Fractional Int) arising from a use of ‘/’
In the first argument of ‘round’, namely ‘(y / 2)’
In the expression: round (y / 2)
In an equation for ‘halfy’: halfy = round (y / 2)
In halfy = round (y/2), you have y :: Int. However, the (/) operator is defined in the Fractional typeclass (which Int is not an instance of; think about which Int could represent e.g. 3/2).
However, there are also the integer division operators div and quot which will give you rounded, Int results. So just replace that definition of halfy with
halfy = y `quot` 2
This will recover your inteded behaviour of halfy since, forgetting about the typing issues for a moment, the fractional part of y/2 is always going to be either 0 or 0.5, and round rounds both towards 0:
Prelude> round (1/2) :: Int
0
Prelude> round (-1/2) :: Int
0
Prelude> 1 `quot` 2 :: Int
0
Prelude> (-1) `quot` 2 :: Int
0
Prelude> (-1) `div` 2 :: Int -- This doesn't recover the same behaviour for negative y!
-1
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