lue-bird/elm-bits

safe, typed bit arrays


Keywords
array-sized, bit, elm, safe, type-safe, typed, typesafe-array, vector
License
MIT
Install
elm-package install lue-bird/elm-bits 4.0.1

Documentation

safe, typed bit arrays

bits

example: id

Most id packages use an opaque type that hold the information. Example from danyx23's Uuid to skim through ↓

type Uuid
    = Uuid String

toString : Uuid -> String
toString =
    \(Uuid string) -> string

fromString : String -> Maybe Uuid
fromString =
    \string ->
        if
            string
                |> Regex.contains
                    (Regex.fromString "^[0-9A-Fa-f]{8,8}-[0-9A-Fa-f]{4,4}-[1-5][0-9A-Fa-f]{3,3}-[8-9A-Ba-b][0-9A-Fa-f]{3,3}-[0-9A-Fa-f]{12,12}$"
                        |> Maybe.withDefault Regex.never
                    )
        then
            string |> Uuid |> Just

        else
            Nothing

generate : Random.Generator Uuid
generate =
    Random.map
        (\thirtyOneHexDigits ->
            Uuid
                ([ thirtyOneHexDigits |> List.take 8 |> List.map mapToHex |> String.fromList
                 , "-"
                 , thirtyOneHexDigits |> List.drop 8 |> List.take 4 |> List.map mapToHex |> String.fromList
                 , "-"
                 , "4"
                 , thirtyOneHexDigits |> List.drop 12 |> List.take 3 |> List.map mapToHex |> String.fromList
                 , "-"
                 , thirtyOneHexDigits |> List.drop 15 |> List.take 1 |> List.map limitDigitRange8ToB |> List.map mapToHex |> String.fromList
                 , thirtyOneHexDigits |> List.drop 16 |> List.take 3 |> List.map mapToHex |> String.fromList
                 , "-"
                 , thirtyOneHexDigits |> List.drop 19 |> List.take 12 |> List.map mapToHex |> String.fromList
                 ]
                    |> String.concat
                )
        )
        (Random.list 31 (Random.int 0 15))

with bits:

import Bit exposing (Bit)

-- from typesafe-array
import ArraySized exposing (ArraySized)
-- from typed-value
import Typed exposing (Typed, Tagged, Public, tag)
-- from bounded-nat
import N exposing (Exactly)
-- generated. See `N`'s module documentation
import N.Local exposing (N128)


random : Random.Generator Uuid
random =
    Random.map (tag Uuid)
        (ArraySized.random Bit.random n128)

type UuidTag
    = Uuid

type alias Uuid =
    Typed
        Tagged
        UuidTag
        Public
        (ArraySized Bit (Exactly (On N128)))

→ type-safe, clean way of storing information

🧩

Bits as a universal way of representing information can be converted from multiple types of data or its bits directly, from characters, from ints...

Bits can also be turned into a variety of representations (→ example)

import Uuid exposing (Uuid)
import Bit exposing (Bit(..))
import Typed exposing (tag, untag)
-- from linear-direction
import Linear exposing (Direction(..))
-- from bburdette/toop
import Toop exposing (T4(..))

uuidUi : Uuid -> Html msg_
uuidUi uuid =
    (uuid |> untag) -- the raw bit array
        |> bitsToHexString
        |> Html.text

uuidFromAllBits : Uuid
uuidFromAllBits =
    -- raw bits
    ArraySized.l16 O I O I I I I O I I I I I O O O
        |> ArraySized.attach Up
            (ArraySized.l16 I I I O O O O I O I I I I O I I)
        ...
        |> tag Uuid

bitsToHexString : ArraySized Bit (In min_ (Up maxX_ To maxPlusX_)) -> String
bitsToHexString bits =
    (bits |> BitArray.toChunksOf n4) -- chunk it up
        |> ArraySized.map toHexChar
        |> ArraySized.toString

{-| Four bits represented as a hex `Char` (0-9 then a-f)
-}
bitToHexChar : ArraySized Bit (In (On N4) (Up maxTo4_ To N4)) -> Char
bitToHexChar =
    \bits ->
        case bits |> ArraySized.to4 of
            T4 O O O O ->
                '0'

            T4 O O O I ->
                '1'

            T4 O O I O ->
                '2'

            T4 O O I I ->
                '3'

            T4 O I O O ->
                '4'

            T4 O I O I ->
                '5'

            T4 O I I O ->
                '6'

            T4 O I I I ->
                '7'

            T4 I O O O ->
                '8'

            T4 I O O I ->
                '9'

            T4 I O I O ->
                'a'

            T4 I O I I ->
                'b'

            T4 I I O O ->
                'c'

            T4 I I O I ->
                'd'

            T4 I I I O ->
                'e'

            T4 I I I I ->
                'f'

Notice how users can

  • build bit arrays safely from different sources of information
  • pattern-match conveniently and safely for different representations

where elm-bits is used

  • elm-morph can create a parser-builder that can even read non-byte-multiple bit counts like 7
  • maybe you built something? Tell us about it ✿

Confused? Hyped? Hit @lue up on anything on slack