Ryan Ingram ryani.spam at gmail.com
Fri Feb 29 03:33:55 EST 2008

```The important thing is the type of "floor":
floor :: (Integral b, RealFrac a) => a -> b
That is, if you have a real, fractional type, and you apply floor to
it, you'll get some integral type.

If you look at allocate', you'll see
allocate' :: (RealFrac in, Integral out) => in -> [in] -> [out]

When you apply this function without any other information, you're
applying Haskell's defaulting rules; I believe you'll get Double for
"in" and Integer for "out".

But in allocate, you have two additional declarations:
allocated = sum vs
therefore, allocated :: out
unallocated = n - sum vs
unallocated :: ?

(-) has type (Num a) => a -> a -> a.  Since both RealFrac and Integral
have Num as a superclass, that constraint goes away.  But you still
end up unifying "in" with "out".  Now you need a type that is both a
real-fractional type and an integer type.  Unsurprisingly, no such
type exists.

To fix:
unallocated = n - fromIntegral (sum vs)

-- ryan

On Fri, Feb 29, 2008 at 12:09 AM, Lloyd Smith <lloyd.g.smith at gmail.com> wrote:
> I have a question about how numeric classes and type checking works. I have two
>  functions that I think should behave the same but don't.
>
>  -- I want to split n things up using a given list of fractions
>  -- for example >allocate' 100 [1/3,1/3,1/3]
>  -- [33,33,33]
>  allocate' n fs = vs
>     where vs = map (floor . (*n)) fs
>
>  -- I want to find anything left over eventually I will want to
>  -- return what is unallocated as well but for now allocated
>  -- and unallocated are not used!
>  allocate n fs = vs
>     where vs = map (floor . (*n)) fs
>           allocated = sum vs
>           unallocated = n - allocated
>
>  When I load these function in the top level everything looks good
>
>  [1 of 1] Compiling Main             ( allocate.hs, interpreted )
>  *Main> allocate' 100 [1/3,1/3,1/3]
>  [33,33,33]
>  *Main> allocate 100 [1/3,1/3,1/3]
>
>  <interactive>:1:0:
>     Ambiguous type variable `t' in the constraints:
>       `Integral t'
>         arising from a use of `allocate' at <interactive>:1:0-25
>       `RealFrac t'
>         arising from a use of `allocate' at <interactive>:1:0-25
>     Probable fix: add a type signature that fixes these type variable(s)
>  *Main>
>
>  I mixed up my types when finding the allocated and unallocated,
>  but I am not sure why it produces an error when unallocated and
>  allocated are never used? Shouldn't the two functions be compiled
>  down to the same thing?
>
>  Suggestions on how to do this more elegantly as well as pointers for
>  understanding numeric
>  type classes would be appreciated.
>
>  TIA
>  Lloyd
>  _______________________________________________