ghci-hexcalc
GHCi as a Hex Calculator interactive
https://github.com/takenobu-hs/ghci-hexcalc
| LTS Haskell 24.17: | 0.1.1.0 | 
| Stackage Nightly 2025-10-31: | 0.1.1.0 | 
| Latest on Hackage: | 0.1.1.0 | 
ghci-hexcalc-0.1.1.0@sha256:f8aecafe6bde8c7966100bde6a49e492d62080bd7ef832cb96a05b3bb87cd977,1573Module documentation for 0.1.1.0
- Data
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 for hex, bin, dec, Tera,Giga,Mega,Kilo, signed and floating
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
             ^^                                                            ^ ^^
Input and convert
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 Hextype.
- Hextype is implemented in unsigned- Word.
- Hextype is 64 bit length on x86_64.
 
- The core type of this package is the 
- Operators and functions:
- Operators in this package begin with .(dot), like.&and.|.
- Most functions align bits to the LSB side.
 
- Operators in this package begin with 
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 | 
| negx1 | Negation. (inv x1 + 1) | 
| signextx1 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” | 
| invx1 | 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 | 
|---|---|
| bit1n1 | Set a bit | 
| bitsn1 n2 | Set bits from n1 to n2 | 
| bitList[n1, n2, … nn] | Set bits with List | 
| byte1n1 | Set a byte | 
| bytesn1 n2 | Set bytes from n1 to n2 | 
| maskn1 | Set bits from 0 to n1 | 
Extract and replace bits
| Operation | Description | 
|---|---|
| getsx1 n1 n2 | Extract bits from n1 to n2 | 
| putsx1 n1 n2 x2 | Replace bits from n1 to n2 | 
| getBit1x1 n1 | Extract bit at n1 | 
| getBitsx1 n1 n2 | Synonym to gets | 
| getByte1x1 n1 | Extract bytes from n1 to 0 | 
| getBytesx1 n1 n2 | Extract bytes from n1 to n2 | 
| putBit1x1 n1 x2 | Replace byte at n1 | 
| putBitsx1 n1 n2 x2 | Synonym to puts | 
| putBytesx1 n1 n2 x2 | Replace bytes from n1 to n2 | 
Set and clear bits
| Operation | Description | 
|---|---|
| sbitsx1 n1 n2 | Set bits from n1 to n2 of x1 | 
| cbitsx1 n1 n2 | Clear bits from n1 to n2 of x1 | 
Get asserted bit positions and count bits
| Operation | Description | 
|---|---|
| pos1x1 | Get bit positions asserted with 1 | 
| pos0x1 | Get bit positions asserted with 0 | 
| rangex1 | Get upper and lower boundaries | 
| count1x1 | Count bit-1 | 
| count0x1 | Count bit-0 | 
Permute
| Operation | Description | 
|---|---|
| bitrevx1 | Reverse bits | 
| byterevx1 | Reverse bytes | 
| gatherx1 x2 | Gather bits from x1 by x2 | 
| scatterx1 x2 x3 | Scatter bits from x3 to x1 by x2 | 
Split and merge
| Operation | Description | 
|---|---|
| splitBitsx1 | Split bits to List | 
| splitBytesx1 | 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] | 
Formatting for hex, bin, dec, Tera,Giga,Mega,Kilo, signed and floating
| 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 | 
| .@hexNn1 | 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 | 
| .@binNn1 | 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 | 
|---|---|
| colorx1 x2 | Highlight bit of x1 specified with x2 | 
| pprfun x1 | Print x1 applied with fun | 
Input and convert
| 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
Changes
Changelog for ghci-hexcalc
0.1.1.0 – Jul. 2019
- Add floating operations:
- .@float, .@double, hex2float, float2hex, hex2double, double2hex
 
0.1.0.2 – Mar. 2019
- Update properties to use suchThatinstead of==>
0.1.0.1 – Oct. 2018
- Update cabal file for test
- Update README and example
0.1.0.0 – Oct. 2018
- First version.
