# Help with types

12 messages
Open this post in threaded view
|

## Help with types

 Hi, I want to make a simple "average" function: average xs = (sum xs)/(length xs) When I try that on ghci I get the following error:      No instance for (Fractional Int)        arising from a use of `/' at :1:17-36      Possible fix: add an instance declaration for (Fractional Int)      In the expression: (sum xs) / (length xs)      In the definition of `average': average xs = (sum xs) / (length xs) Ok, so 'sum' is of type (Num a => [a] -> a), length is of type ([a] -> Int) and (/) is of type (Fractional a => a -> a -> a). Can someone explain how I can "add an instance declaration" to my function so as to make all these types compatible? Thanks, Daniel.
Open this post in threaded view
|

## Help with types

 Am Donnerstag 23 April 2009 14:57:58 schrieb Daniel Carrera: > Hi, > > I want to make a simple "average" function: > > average xs = (sum xs)/(length xs) > > When I try that on ghci I get the following error: > >      No instance for (Fractional Int) >        arising from a use of `/' at :1:17-36 >      Possible fix: add an instance declaration for (Fractional Int) >      In the expression: (sum xs) / (length xs) >      In the definition of `average': average xs = (sum xs) / (length xs) > > Ok, so 'sum' is of type (Num a => [a] -> a), length is of type ([a] -> > Int) and (/) is of type (Fractional a => a -> a -> a). Can someone > explain how I can "add an instance declaration" to my function so as to > make all these types compatible? Don't. (you wouldn't add the instance declaration to the function, anyway, but to your module) Try explicitly converting the length to the appropriate type: average xs = sum xs / fromIntegral (length xs) will yield a working (albeit inefficient) average :: Fractional a => [a] -> a > > Thanks, > Daniel.
Open this post in threaded view
|

## Help with types

 Daniel Fischer wrote: > Try explicitly converting the length to the appropriate type: > > average xs = sum xs / fromIntegral (length xs) Thanks. Could you help me understand what's happening? 1. length returns Int. 2. sum returns Num. 3. (/) wants Fractional. It looks like (/) is happy with Num but doesn't like Int. This surprises me. I would have thought that Fractional is a kind of Num and Int is a kind of Fractional, so a function that expects Fractional would be happy with an Int but maybe not with a Num. But clearly that's not the way it works. 'fromIntegral' converts Int to Num. So obviously, Num is good and Int is bad. But I don't really get why. > will yield a working (albeit inefficient) > average :: Fractional a => [a] -> a Why is it inefficient? How would you make it efficient? Thanks for the help. Cheers, Daniel.
Open this post in threaded view
|

## Help with types

 There is a chapter in Real World Haskell [1] devoted to this exact question on this exact piece of code. hth, -deech [1] http://book.realworldhaskell.org/read/profiling-and-optimization.htmlOn Thu, Apr 23, 2009 at 8:52 AM, Daniel Carrera < [hidden email]> wrote: > Daniel Fischer wrote: > >> Try explicitly converting the length to the appropriate type: >> >> average xs = sum xs / fromIntegral (length xs) >> > > Thanks. Could you help me understand what's happening? > > 1. length returns Int. > 2. sum returns Num. > 3. (/) wants Fractional. > > It looks like (/) is happy with Num but doesn't like Int. This surprises > me. I would have thought that Fractional is a kind of Num and Int is a kind > of Fractional, so a function that expects Fractional would be happy with an > Int but maybe not with a Num. But clearly that's not the way it works. > > 'fromIntegral' converts Int to Num. So obviously, Num is good and Int is > bad. But I don't really get why. > > >  will yield a working (albeit inefficient) >> average :: Fractional a => [a] -> a >> > > Why is it inefficient? How would you make it efficient? > > Thanks for the help. > > Cheers, > > Daniel. > _______________________________________________ > Beginners mailing list > [hidden email] > http://www.haskell.org/mailman/listinfo/beginners> -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20090423/4ba489ef/attachment.htm
Open this post in threaded view
|

## Help with types

 In reply to this post by Daniel Carrera-4 2009/04/23 Daniel Carrera <[hidden email]>: > It looks like (/) is happy with Num but doesn't like Int. This > surprises me.  I would have thought that Fractional is a kind > of Num and Int is a kind of Fractional, so a function that > expects Fractional would be happy with an Int but maybe not > with a Num. But clearly that's not the way it works.   In GHCi, let's have a look:     Prelude> :info Int     data Int = GHC.Types.I# GHC.Prim.Int#   -- Defined in GHC.Types     instance Bounded Int -- Defined in GHC.Enum     instance Enum Int -- Defined in GHC.Enum     instance Eq Int -- Defined in GHC.Base     instance Integral Int -- Defined in GHC.Real     instance Num Int -- Defined in GHC.Num     instance Ord Int -- Defined in GHC.Base     instance Read Int -- Defined in GHC.Read     instance Real Int -- Defined in GHC.Real     instance Show Int -- Defined in GHC.Show   So `Int` is not actually a kind of `Fractional` (it's   `Integral`, in fact).     Prelude> :t (/)     (/) :: forall a. (Fractional a) => a -> a -> a   So `(/)` needs some `t` that is in `Fractional`. > 'fromIntegral' converts Int to Num. So obviously, Num is good and Int is > bad. But I don't really get why.   Actually, `fromIntegral` takes any type `t` that is in   `Integral` and makes it into some other type in `Num` as   appropriate. You can use `fromIntegral` to go from `Int` to   `Integer` or `Word32`, as well.   To work with `(/)` we need a type that is in `Num` and in   `Fractional`. The compiler defaults these *class constraints*   to select, say `Double`. Then `fromIntegral` -- which can take   any `Num` to any other `Num` -- does the "cast" from `Int` to   `Double` for us. -- Jason Dusek
Open this post in threaded view
|

## Help with types

 In reply to this post by Daniel Carrera-4 On 23 Apr 2009, at 15:52, Daniel Carrera wrote: > Daniel Fischer wrote: >> Try explicitly converting the length to the appropriate type: >> average xs = sum xs / fromIntegral (length xs) > > Thanks. Could you help me understand what's happening? > > 1. length returns Int. > 2. sum returns Num. > 3. (/) wants Fractional. > > It looks like (/) is happy with Num but doesn't like Int. This   > surprises me. I would have thought that Fractional is a kind of Num   > and Int is a kind of Fractional Int isn't a Fractional because it can't represent fractional numbers. Bob
Open this post in threaded view
|

## Help with types

 In reply to this post by aditya siram-2 aditya siram wrote: > There is a chapter in Real World Haskell [1] devoted to this exact > question on this exact piece of code. > > hth, > -deech > > [1] http://book.realworldhaskell.org/read/profiling-and-optimization.htmlWow. Indeed, that is the exact same piece of code. Thanks. Daniel.
Open this post in threaded view
|

## Help with types

 In reply to this post by Thomas Davie Thomas Davie wrote: >> It looks like (/) is happy with Num but doesn't like Int. This >> surprises me. I would have thought that Fractional is a kind of Num >> and Int is a kind of Fractional > > Int isn't a Fractional because it can't represent fractional numbers. Sure, but any integer is trivially also a fraction, so I would think that it would be an acceptable input for (/). On the other hand, if it is at all possible for a Num to contain something that cannot be converted to a fraction, then a Num should not be a valid input for (/).
Open this post in threaded view
|

## Help with types

 2009/04/23 Daniel Carrera <[hidden email]>: > ...if it is at all possible for a Num to contain something > that cannot be converted to a fraction, then a Num should not > be a valid input for (/).   And it isn't.     Prelude> :t (/)     (/) :: forall a. (Fractional a) => a -> a -> a -- Jason Dusek
Open this post in threaded view
|

## Help with types

 In reply to this post by Daniel Carrera-4 On 23 Apr 2009, at 16:25, Daniel Carrera wrote: > Thomas Davie wrote: >>> It looks like (/) is happy with Num but doesn't like Int. This   >>> surprises me. I would have thought that Fractional is a kind of   >>> Num and Int is a kind of Fractional >> Int isn't a Fractional because it can't represent fractional numbers. > > Sure, but any integer is trivially also a fraction, so I would think   > that it would be an acceptable input for (/). On the other hand, if   > it is at all possible for a Num to contain something that cannot be   > converted to a fraction, then a Num should not be a valid input for   > (/). The problem here is that (/) also *outputs* that type ? if you can't   represent a fraction, how do you give the result of 1/4? Bob