Some notes on using unboxed types in Haskell, and in particular, notes on creating a boxed wrapper for the integer-gmp library function `integerLog2# :: Integer -> Int#`

which returns an unboxed type.

`{-# LANGUAGE MagicHash #-}`

import GHC.Exts(Int(I#));

import GHC.Integer.Logarithms(integerLog2#);

`integerLog2 :: Integer -> Int;`

integerLog2 i = if i < 1

then error "must be positive"

-- because integerLog2# does no bounds checking

else I# (integerLog2# i);

The pragma MagicHash prevents GHC from interpreting the hash symbol as an operator. Without it, one gets error messages like this:

parse error on input `#'

not in scope: `#'

It would be nice if GHC emitted a suggestion of MagicHash on errors like this.

The constructor I# is findable using Hoogle, searching for Int#->Int.

One must use parentheses around the argument to I#. The standard trick of removing parentheses with the dollar sign results in an error:

`bad1 i = I# $ integerLog2# i;`

Couldn't match kind `*' with `#'

When matching types

r0 :: *

GHC.Prim.Int# :: #

Using the composition operator in point-free style fails similarly:

`bad2 = I# . integerLog2#;`

Couldn't match kind `*' with `#'

When matching types

b0 :: *

GHC.Prim.Int# :: #

Expected type: b0 -> Int

Actual type: GHC.Prim.Int# -> Int

In the first argument of `(.)', namely `I#'

Unboxed types are a different "kind", the # kind, than boxed types, which are a * kind.

## No comments :

Post a Comment