I am doing this as an pattern matching exercise.
I would like to have a function that will work on both Num
type and List
type. For example:
double 20
double [1,2,3,4,5]
The code works till
double [] = []
double (x : xs) = (2 * x) : (double xs)
main = do
let x = [1,2,3,4,5]
print (double x)
But when I try:
double x = x x
double [] = []
double (x : xs) = (2 * x) : (double xs)
main = do
let x = [1,2,3,4,5]
print (double 20)
print (double x)
It gives error.
What should be done here?
CodePudding user response:
As mentioned by chi, it's better to have separate functions. I would add that, especially whilst you're learning, it's a good habit to think about and write the type signatures of your functions.
For the sake of answering your question, you can still do this.
You tell Haskell that the Integer
and [Integer]
data types "can be doubled", and then define how you do that for each type. I understand that this is more advanced than what you're asking however :)
{-# LANGUAGE FlexibleInstances #-}
class CanDouble a where
double :: a -> a
instance CanDouble Integer where
double = (*2)
instance CanDouble [Integer] where
double [] = []
double (x:xs) = double x : double xs
> double 5
10
> double [1,2,3]
[2,4,6]
CodePudding user response:
In addition to using typeclasses as in Haren's answer, you can use Either Int [Int]
.
double :: Either Int [Int] -> Either Int [Int]
double (Left n) = Left $ n * 2
double (Right lst) = Right $ map (* 2) lst
ghci> double (Left 5)
Left 10
ghci> double (Right [1,2,3])
Right [2,4,6]