[Haskell] (no subject)

Brandon S. Allbery KF8NH allbery at ece.cmu.edu
Wed Sep 5 17:28:58 EDT 2007


On Sep 5, 2007, at 21:10 , Tomi Owens wrote:

> Prelude> let f (a,b) = a * floor (100000/b)
> Prelude> f(2,5)
> 40000
>
> This function works just as I want it to.
>
> Now I try creating a list:
>
> Prelude> [(a2+b2,a)| a <- [1..4] , b<- [1..4], a2+b2<20, b<=a]
> [(2,1),(5,2),(8,2),(10,3),(13,3),(18,3),(17,4)]
>
> and this works
> So now I try to apply the function to the list:
>
> Prelude> map (f) [(a2+b2,a)| a <- [1..4] , b<- [1..4], a2+b2<20, b<=a]
>
> and I get this result:
>
> <interactive>:1:5:
>    Ambiguous type variable `t' in the constraints:
>      `Integral t' arising from use of `f' at <interactive>:1:5
>      `RealFrac t' arising from use of `f' at <interactive>:1:5
>    Probable fix: add a type signature that fixes these type variable 
> (s)
>
>
> I'm sorry, but I don't quite get how to set the type signature and  
> how it will apply to my function...

The problem here is that (assuming the a\sup{2} etc. are actually  
a^2) the (^) operator expects and returns Integrals, but (/) requires  
a RealFrac.  Thus, the type of your list comprehension is inferred to  
be [(Integer,Integer)] but needs to be RealFrac a => [(Integer,a)]  
(or, more simply, [(Integer,Double)].

   Prelude> let f (a,b) = a * floor (100000/b)
   Prelude> :t f
   f :: (RealFrac t1, Integral t) => (t, t1) -> t
   Prelude> let v :: [(Integer,Double)]; v = [(a^2 + b^2,fromIntegral  
a) | a <- [1..4], b <- [1..4], a^2 + b^2 < 20, b <= a]
   Prelude> :t v
   v :: [(Integer, Double)]
   Prelude> map f v
   [200000,250000,400000,333330,433329,599994,425000]

-- 
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery at kf8nh.com
system administrator [openafs,heimdal,too many hats] allbery at ece.cmu.edu
electrical and computer engineering, carnegie mellon university    KF8NH




More information about the Haskell mailing list