
GHCi as a Hex-Calculator interactive
The GHCi (REPL for Haskell) is a very useful interactive tool, it's not only for debugging :)
This package "ghci-hexcalc" is an interactive hex-calculator using Haskell/GHCi.
This is a simple and casual tool like Perl and Excel for our daily work.
Interactive oriented features:
- Short-named operators and functions
 
- Show values in hexadecimal format by default
 
- Suppress type annotation of numeric literals by type inference
 
- Postfix-notation available
 
- Highlight available
 
See also description on Hackage.
Contents
Run
Bare GHCi:
$ ghci src/Data/GHex.hs
or
$ ghci -ghci-script example/example.ghci
Stack:
$ stack exec -- ghci  src/Data/GHex.hs
Example of use
Numeric literals by Hex type annotation
The value of Hex type is shown as hexadecimal format.
ghci> 1 :: Hex
0x0000_0000_0000_0001
ghci> 0xff :: Hex
0x0000_0000_0000_00ff
ghci> 0b1011 :: Hex
0x0000_0000_0000_000b
ghci> 16 + 3 :: Hex
0x0000_0000_0000_0013
Variables on GHCi
You could use variables of Haskell syntax on GHCi.
ghci> x = 255 :: Hex
ghci> x + 3
ghci> y = it       -- `it` is GHCi's variable. It stores the previous result.
Arithmetic operations
You could also use arithmetic operators in Hex type.
ghci> x + 3
ghci> (x * 256) -1
ghci> x + 2^10
ghci> neg x
Logical operations
Numeric literals applied to functions of this package are inferred as Hex type.
ghci> 0xff .& 6
ghci> 256 .| 16
ghci> 100 .^ 5
ghci> inv 255
Shift operations
ghci> 1 .<< 16
ghci> 256 .>> 1
Div and mod operations
ghci> 0xff0000 ./ 256
ghci> 0xfedc .% 256
Generate bit and byte with position
ghci> bit1 15
0x0000_0000_0000_8000
ghci> bits 7 4
0x0000_0000_0000_00f0
ghci> bitList [15, 14, 1]
0x0000_0000_0000_c002
ghci> byte1 2
0x0000_0000_00ff_0000
ghci> bytes 4 3
0x0000_00ff_ff00_0000
Extract and replace bits
ghci> gets 0xabcd 15 12
0x0000_0000_0000_000a
ghci> puts 0xabcd 15 12 7
0x0000_0000_0000_7bcd
Set and clear bits
ghci> sbits 0x1234 11 8
0x0000_0000_0000_1f34
ghci> cbits 0x1234 7 4
0x0000_0000_0000_1204
Get asserted bit positions and count bits
ghci> pos1 0x0081
[7,0]
ghci> pos0 $ inv 0x0100
[8]
ghci> count1 0b11001
3
Permute, split and merge
ghci> gather 0x12345678 0x0ff000f0
0x0000_0000_0000_0237
ghci> scatter 0x12345678 0xff00ff00 0xabcd
0x0000_0000_ab34_cd78
ghci> (3,0b101) .++ (2,0b11)
(5,0x0000_0000_0000_0017)
Predefined-constants
ghci> mega
0x0000_0000_0010_0000
ghci> giga
0x0000_0000_4000_0000
ghci> 4 * giga - 1
0x0000_0000_ffff_ffff
ghci> 2^32 ./ giga
0x0000_0000_0000_0004
Postfix-notation
The operator .@ is an operator for postfix notation.
It's the same as Data.Function.(&).
The following two are the same:
ghci> pos1 0xf0
[7,6,5,4]
ghci> 0xf0 .@pos1
[7,6,5,4]
Formatting functions convert a Hex type value to a string type for each format.
ghci> 2^16 .@hex
"0x0000_0000_0001_0000"
ghci> 100 .@bin
"0b110_0100"
ghci> 100 .@bin16
"0b0000_0000_0110_0100"
ghci> giga .@dec
"1073741824"
ghci> bit 43 .@decT
"8"
ghci> 0xffffffffffffffff .@signed
"-1"
ghci> 0x3fc00000 .@float
"1.5"
Hilighting specified bits
The function color highlights specified bits. It inverts the color in the ANSI sequence for the specified bits.
ghci> 0xff .@color (bits 7 4)
0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1111_1111
                                                                        ^^^^
ghci> 0xffffffff .@color mega
0b0000_0000_0000_0000_0000_0000_0000_0000_1111_1111_1111_1111_1111_1111_1111_1111
                                                       ^
ghci> 0 .@color (bitList [54,53,4,3,2])
0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000
             ^^                                                            ^ ^^
The function inputRawHexIO  inputs a string and converts it to a Hex type.
ghci> inputRawHexIO
ff aa  (your input)
ghci> x = it
ghci> x
0x0000_0000_0000_ffaa
ghci> x <- inputRawHexIO
ff aa  (your input)
ghci> x
0x0000_0000_0000_ffaa
Floating conversion examples
ghci> float2hex 1.0
0x0000_0000_3f80_0000
ghci> hex2float 0x3fc00000
1.5
ghci> double2hex 1.0
0x3ff0_0000_0000_0000
ghci> hex2double 0x40091eb851eb851f
3.14
Combination examples
ghci> x .| bit1 18
ghci> (x .<< 4) .& 0xf0
ghci> bit1 33 ./ giga
ghci> 2 * mega .@dec
ghci> 4 * tera .@pos1
ghci> foldr1 (.|) [0xa, 0xcc, 0xd1b]
ghci> 0 .@color (tera .| giga .| mega .| kilo)
Using Data.Bits library
Hex type is deriving Data.Bits type. So you could use functions of Data.Bits.
ghci> x `testBit` 8
ghci> x `clearBit` 15
ghci> x .&. 0xff
ghci> x `rotateL` 4
ghci> countLeadingZeros x
Clear screen
ghci> cls
Simple help
Show simple usage:
ghci> usage
Listing APIs with :browse ghci command:
ghci> :browse
newtype Hex = Hex Word
(.&) :: Hex -> Hex -> Hex
(.|) :: Hex -> Hex -> Hex
(.^) :: Hex -> Hex -> Hex
inv :: Hex -> Hex
  :
When you run with ghci -haddock, you could also use :doc ghci command (ghc8.6 or later):
ghci> :doc bits
 Set bits from n1 to n2
 >>> bits 15 8
 0x0000_0000_0000_ff00
Specification
Please see also Hackage document in detail.
General
- Core type:
- The core type of this package is the 
Hex type.
 
Hex type is implemented in unsigned Word.
 
Hex type is 64 bit length on x86_64.
 
 
- Operators and functions:
- Operators in this package begin with 
.(dot), like .& and .|.
 
- Most functions align bits to the LSB side.
 
 
Numeric literals by Hex type annotation
| Operation | 
Description | 
:: Hex | 
Type annotation for basic type Hex | 
255 :: Hex | 
Decimal number literal | 
0xff :: Hex | 
Hexadecimal number literal | 
0b1101 :: Hex | 
binary number literal | 
Derived operations
| Operation | 
Description | 
| Many operations | 
Eq, Ord, Num, Enum, Real, Bounded, Integral, Bits and FiniteBits class available | 
Postfix operator
| Operation | 
Description | 
.@ | 
Postfix-notation operator | 
Arithmetic operations
| Operation | 
Description | 
+, -, *, ^, ... | 
Num, Real class available | 
neg x1 | 
Negation. (inv x1 + 1) | 
signext x1 n1 | 
Sign extention | 
x1 ./ x2 | 
Integer division | 
x1 .% x2 | 
Integer modulo | 
Logical operations
| Operation | 
Description | 
x1 .& x2 | 
Bitwise "and" | 
x1 .| x2 | 
Bitwise "or" | 
x1 .^ x2 | 
Bitwise "xor" | 
inv x1 | 
Bitwise "not" (invert) | 
Shift operations
| Operation | 
Description | 
x1 .<< n1 | 
Logical left shift | 
x1 .>> n1 | 
Logical right shift | 
Generate bit and byte with position
| Operation | 
Description | 
bit1 n1 | 
Set a bit | 
bits n1 n2 | 
Set bits from n1 to n2 | 
bitList [n1, n2, ... nn] | 
Set bits with List | 
byte1 n1 | 
Set a byte | 
bytes n1 n2 | 
Set bytes from n1 to n2 | 
mask n1 | 
Set bits from 0 to n1 | 
Extract and replace bits
| Operation | 
Description | 
gets x1 n1 n2 | 
Extract bits from n1 to n2 | 
puts x1 n1 n2 x2 | 
Replace bits from n1 to n2 | 
 | 
 | 
getBit1  x1 n1 | 
Extract bit at n1 | 
getBits  x1 n1 n2 | 
Synonym to gets | 
getByte1 x1 n1 | 
Extract bytes from n1 to 0 | 
getBytes x1 n1 n2 | 
Extract bytes from n1 to n2 | 
putBit1  x1 n1 x2 | 
Replace byte at n1 | 
putBits  x1 n1 n2 x2 | 
Synonym to puts | 
putBytes x1 n1 n2 x2 | 
Replace bytes from n1 to n2 | 
Set and clear bits
| Operation | 
Description | 
sbits x1 n1 n2 | 
Set bits from n1 to n2 of x1 | 
cbits x1 n1 n2 | 
Clear bits from n1 to n2 of x1 | 
Get asserted bit positions and count bits
| Operation | 
Description | 
pos1 x1 | 
Get bit positions asserted with 1 | 
pos0 x1 | 
Get bit positions asserted with 0 | 
 | 
 | 
range x1 | 
Get upper and lower boundaries | 
 | 
 | 
count1 x1 | 
Count bit-1 | 
count0 x1 | 
Count bit-0 | 
Permute
| Operation | 
Description | 
bitrev x1 | 
Reverse bits | 
byterev x1 | 
Reverse bytes | 
 | 
 | 
gather x1 x2 | 
Gather bits from x1 by x2 | 
scatter x1 x2 x3 | 
Scatter bits from x3 to x1 by x2 | 
Split and merge
| Operation | 
Description | 
splitBits x1 | 
Split bits to List | 
splitBytes x1 | 
Split bytes to List | 
mergeBits [x1, x2, .. xn] | 
Merge bits from List | 
mergeBytes [x1, x2, .. xn] | 
Merge bytes from List | 
 | 
 | 
splitPairs [n1, .. nn] x1 | 
Split bits to pair of (length,Hex) | 
mergePairs [(n1,x1),..] | 
Merge bits from pair of (length,Hex) | 
(n1,x1) .++ (n2,x2) | 
Concatinate pairs of (length,Hex) | 
Predefined-constants
| Constant | 
Description | 
exa | 
2^60 (It's not 10^18) | 
peta | 
2^50 (It's not 10^15) | 
tera | 
2^40 (It's not 10^12) | 
giga | 
2^30 (It's not 10^9) | 
mega | 
2^20 (It's not 10^6) | 
kilo | 
2^10 (It's not 10^3) | 
 | 
 | 
zero | 
0 | 
one | 
1 | 
all0 | 
0x0 | 
all1 | 
inv all0 | 
 | 
 | 
hexBitSize | 
64 on x86_64. Thus size of Word | 
hexBitSeq | 
[hexBitSize-1, hexBitSize-2, .. 0] | 
| Operation | 
Description | 
.@hex | 
Show in hexadecimal string | 
.@hex8 | 
Show in hexadecimal string of 8bit | 
.@hex16 | 
Show in hexadecimal string of 16bit | 
.@hex32 | 
Show in hexadecimal string of 32bit | 
.@hex64 | 
Show in hexadecimal string of 64bit | 
.@hexN n1 | 
Show in hexadecimal string of n1 bit | 
 | 
 | 
.@bin | 
Show in binary string | 
.@bin8 | 
Show in binary string of 8bit | 
.@bin16 | 
Show in binary string of 16bit | 
.@bin32 | 
Show in binary string of 32bit | 
.@bin64 | 
Show in binary string of 64bit | 
.@binN n1 | 
Show in binary string of n1 bit | 
 | 
 | 
.@dec | 
Show in decimal string | 
.@decE | 
Show in decimal of Exa unit | 
.@decP | 
Show in decimal of Peta unit | 
.@decT | 
Show in decimal of Tera unit | 
.@decG | 
Show in decimal of Giga unit | 
.@decM | 
Show in decimal of Mega unit | 
.@decK | 
Show in decimal of Kilo unit | 
 | 
 | 
.@signed | 
Show in singed decimal with Word | 
 | 
 | 
.@float | 
Show in float string | 
.@double | 
Show in double string | 
 | 
 | 
.@hexSized | 
Show in hexadecimal string of (len,Hex) | 
.@binSized | 
Show in binary string of (len,Hex) | 
Hilighting and pretty-print
| Operation | 
Description | 
color x1 x2 | 
Highlight bit of x1 specified with x2 | 
ppr fun x1 | 
Print x1 applied with fun | 
| Operation | 
Description | 
inputRawHexIO | 
Input string and convert to Hex type | 
Floating convert
| Operation | 
Description | 
float2hex | 
Convert Float to Hex type | 
hex2float | 
Convert Hex to Float type | 
double2hex | 
Convert Double to Hex type | 
hex2double | 
Convert Hex to Double type | 
Miscellaneous
| Operation | 
Description | 
cls | 
Clear screen by ANSI sequence | 
usage | 
Show simple help | 
Appendix
GHC language extention for numeric literals
When -XBinaryLiterals extention enabled, you can use binary literals on GHC and GHCi, like 0b1101.
When -XNumericUnderscores extention enabled, you can use underscores in numeric literals on GHC and GHCi, like 0xff_ff.
-XNumericUnderscores extension is available GHC 8.6 or later.
GHC language extensions can be described in ~/.ghci or ./ghci file:
:set -XBinaryLiterals
:set -XNumericUnderscores
GHC language extensions can also be specified as an option when starting GHC and GHCi:
$ ghci -XBinaryLiterals -XNumericUnderscores
Shell alias
It is useful to set the alias of the shell:
alias ghex="(cd $XXX/ghci-hexcalc; ghci -ghci-script example/example.ghci)"
Expression evaluation mode of GHC
You can also run in one shot mode (a expression evaluation mod) by ghc -e:
$ ghc src/Data/GHex.hs -e '4 * giga'
0x0000_0004_0000_0000
Default declaration on GHCi
With the default declaration, integer literals are inferred as Hex types.
ghci> default (Hex)
ghci> 255
0x0000_0000_0000_00ff