pu239ppy
pu239ppy

Reputation: 129

Haskell bitwise operators in Data.Bits

I am new to Haskell and am trying to use bitwise operations from Data.Bits. Every time I try I get an error message

Prelude Data.Bits> 1 `shiftL` 16

<interactive>:1:0:
    Ambiguous type variable `t' in the constraint:
      `Bits t' arising from a use of `shiftL' at <interactive>:1:0-12
    Probable fix: add a type signature that fixes these type variable(s)

This happens for a number of operations, I also tried .|. and .&.

I must be missing something very simple, please let me know if you can spot the problem

Upvotes: 3

Views: 7584

Answers (2)

Daniel Fischer
Daniel Fischer

Reputation: 183878

ghci doesn't know what type to choose. However, that shouldn't be so:

Prelude Data.Bits> 1 `shiftL` 16
65536

From the expression entered at the prompt, the constraint Bits t is inferred (also Num t, but Num is a superclass of Bits, hence implied; and since it is to be displayed by the interpreter, also Show t).

Now, since one of the constraints is a numeric class and all of the classes are defined in the Prelude or the standard libraries, the ambiguous type variable t is eligible for defaulting. In the absence of explicit default declarations, the ambiguity is resolved by choosing Integer as the type.

Off the top of my head, I can't think of a language extension that would prevent the resolution of the ambiguity by defaulting, so the conclusion is that your ghci is old. The Bits class was not in the standard libraries as defined by the Haskell98 report, so a Bits constraint was not eligible for defaulting in compilers adhering to that standard, for example GHC < 7.

In that case, the immediate workaround is to specify a type signature,

Prelude Data.Bits> 1 `shiftL` 16 :: Int
65536

and the fix to your problem is to upgrade your GHC to a version adhering to the newer Haskell2010 standard.

Upvotes: 3

zdav
zdav

Reputation: 2748

In the interactive session, Haskell can't infer the types of 1 and 16. The solution then, is to give a hint:

> :m +Data.Bits
> let a = 1 :: Int
> let b = 16 :: Int
> a `shiftL` b
65535
>

Upvotes: 9

Related Questions