[Haskell-beginners] Cannot compile "where" in a function

Brent Yorgey byorgey at seas.upenn.edu
Sun Dec 16 18:21:15 CET 2012


On Sun, Dec 16, 2012 at 06:08:20PM +0100, Trung Quang Nguyen wrote:
> Hi there,
> 
> I'm trying to implement Reverse Polish notation calculator from
> learnyouhaskell.com. I want to add one more operator "/", but I cannot
> compile. I comment out the line --func (x:y:ys) "/" = (y / x):ys, thing
> goes well again. Any body knows the cause of this problem?
> 
> --rpn.hs
> import System.Environment
> import Data.List
> 
> solveRPN :: (Num a, Read a) => String -> a
> solveRPN = head . foldl func [] . words
>     where
>         func (x:y:ys) "+" = (y + x):ys
>         func (x:y:ys) "-" = (y - x):ys
>         func (x:y:ys) "*" = (y * x):ys
>         --func (x:y:ys) "/" = (y / x):ys
>         func xs numStr = read numStr:xs
> 
> main = do
>     (x:_) <- getArgs
>     putStrLn $ show $ solveRPN x
> 
> I got this:
> ~/w/r/s/haskell> ghc --make rpn
> [1 of 1] Compiling Main             ( rpn.hs, rpn.o )
> 
> rpn.hs:5:25:
>     Could not deduce (Fractional a) arising from a use of `func'
>     from the context (Num a, Read a)

The problem is that you can only use the (/) operator on types which
are instances of the Fractional type class, but you have stated that
your function should work for any type as long as it is an instance of
Num.  But being an instance of Num does not imply an instance of
Fractional; your function would not work for any type which is an
instance of Num but not of Fractional, such as Int.

If you only want to use solveRPN with Fractional types like Double or
Rational, you can just change the Num constraint to a Fractional
constraint.  If you want solveRPN to work with non-fractional types
like Int, then you have to decide what exactly division is supposed to
mean.  Perhaps you want to use 'div' instead of (/) (in which case you
have to use an Integral constraint instead of Num)?

-Brent



More information about the Beginners mailing list