user7826451
user7826451

Reputation:

Ambiguous type variable ‘a0’ arising from a use of ‘print’ using simple function

I am implementing a function in Haskell: function

I have written

f x k = h x k

h x i = x^i/factorial i


factorial n = foldl (*) 1 [1..n]

where h is a helper function that will be used in f function when summing. But right now when I try to use the function I get this error:

<interactive>:109:1: error:
    • Ambiguous type variable ‘a0’ arising from a use of ‘print’
      prevents the constraint ‘(Show a0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘a0’ should be.
      These potential instances exist:
        instance Show Ordering -- Defined in ‘GHC.Show’
        instance Show Integer -- Defined in ‘GHC.Show’
        instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
        ...plus 22 others
        ...plus 19 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In a stmt of an interactive GHCi command: print it

Upvotes: 2

Views: 121

Answers (2)

Reinier Torenbeek
Reinier Torenbeek

Reputation: 17383

Not a direct answer to your question, but still a relevant observation: your function can be calculated more efficiently (and will be more fun to implement) when you rewrite it like this:

Alternative form to g(x,k)

Upvotes: 1

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477180

If we inspect the type of h, we see:

h :: (Fractional a, Integral a) => a -> a -> a

So it means that your number should be both Fractional and Integral. Although strictly speaking you can create numbers in Haskell that are members of both typeclasses, it does not make much sense. A number that is Integral is not Fractional and vice versa.

The reason this happens is because we make use of (/) :: Fractional a => a -> a. It thus requires both the numerator and denominator to be of the same type, and members of Fractional. This thus means that factorial i should have that type a, and thus by extent i itself. But i should be integral because of the use of (^) :: (Num a, Integral b) => a -> b -> a.

You can make use of fromIntegral :: (Integral a, Num b) => a -> b to convert the given integral number to another type that is a member of Num:

h :: (Floating a, Integral b) => a -> a -> b
h x i = x^i / fromIntegral (factorial i)

This gives us for example:

Prelude> h 2 1
2.0
Prelude> h 2 2
2.0
Prelude> h 2 3
1.3333333333333333

Upvotes: 4

Related Questions