Home > Enterprise >  Function that works on both Num and List
Function that works on both Num and List

Time:11-02

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]
  • Related