Newbie question about function type constraints

Hi, can someone explain to me why i cannot define meanList as: meanList :: (Integral a, Fractional b) => [a] -> a meanList xs = (sumList xs) / (lengthList xs) I want to restrict the function to only accept lists like [1,2,3] and return answer 2.0 sumList :: (Num a) => [a] -> a sumList [] = 0 sumList (x:xs) = x + (sumList xs) lengthList :: (Num a) => [t] -> a lengthList [] = 0 lengthList (_:xs) = 1 + (lengthList xs)

Hello, this works too: meanList :: (Fractional a) => [a] -> a meanList xs = (sumList xs) / (lengthList xs) sumList :: (Fractional a) => [a] -> a sumList [] = 0 sumList (x:xs) = x + (sumList xs) lengthList :: (Fractional a) => [t] -> a lengthList [] = 0 lengthList (_:xs) = 1 + (lengthList xs)

Am 22.09.16 um 15:19 schrieb Lai Boon Hui:
Hi, can someone explain to me why i cannot define meanList as:
meanList :: (Integral a, Fractional b) => [a] -> a meanList xs = (sumList xs) / (lengthList xs)
I want to restrict the function to only accept lists like [1,2,3] and return answer 2.0
It will work like this: meanList :: (Integral a, Fractional b) => [a] -> b meanList xs = fromIntegral (sumList xs) / (lengthList xs) You probably meant -> b in the type signature, that was a typo. And you need to insert fromIntegral to convert to Fractional before you can divide. Now that I see it I am beginning to wonder why it works, though, because I was just about to insert another fromIntegral before lengthList ...
sumList :: (Num a) => [a] -> a sumList [] = 0 sumList (x:xs) = x + (sumList xs)
lengthList :: (Num a) => [t] -> a lengthList [] = 0 lengthList (_:xs) = 1 + (lengthList xs)
Hope this helps
--
Harald Bögeholz

It will work like this: meanList :: (Integral a, Fractional b) => [a] -> b meanList xs = fromIntegral (sumList xs) / (lengthList xs)
You probably meant -> b in the type signature, that was a typo.
And you need to insert fromIntegral to convert to Fractional before you can divide. Now that I see it I am beginning to wonder why it works, though, because I was just about to insert another fromIntegral before lengthList ... It works because in this case lengthList uses the fractional type b to
On 22/09/2016 16:08, Harald Bögeholz wrote: perfom its summation (it doesn't care about the type of the elements in xs). Cheers Sylvain

Hi, You can define it, but in practice there is no instance of "a" that satisfies both constraints: Integral a and Fractional a
meanList ([1,2,3] :: [Int])
<interactive>:4:1: error: • No instance for (Fractional Int) arising from a use of ‘meanList’
meanList ([1,2,3] :: [Float])
<interactive>:5:1: error: • No instance for (Integral Float) arising from a use of ‘meanList’ What you probably want is: meanList :: (Integral a, Fractional b) => [a] -> b meanList xs = fromIntegral (sumList xs) / fromIntegral (lengthList xs) Where we convert from the integral type "a" to the fractional type "b" before performing the division.
meanList ([1,2,3] :: [Int]) 2.0
Cheers Sylvain On 22/09/2016 15:19, Lai Boon Hui wrote:
Hi, can someone explain to me why i cannot define meanList as:
meanList :: (Integral a, Fractional b) => [a] -> a meanList xs = (sumList xs) / (lengthList xs)
I want to restrict the function to only accept lists like [1,2,3] and return answer 2.0
sumList :: (Num a) => [a] -> a sumList [] = 0 sumList (x:xs) = x + (sumList xs)
lengthList :: (Num a) => [t] -> a lengthList [] = 0 lengthList (_:xs) = 1 + (lengthList xs)
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
participants (4)
-
Harald Bögeholz
-
Imants Cekusins
-
Lai Boon Hui
-
Sylvain Henry