tapes, cords and sum types

This commit is contained in:
iko 2023-05-31 16:50:28 +03:00
parent 672e34830b
commit d4b214ea1a
Signed by untrusted user: iko
GPG Key ID: 82C257048D1026F2
2 changed files with 90 additions and 3 deletions

View File

@ -1,17 +1,21 @@
module Urbit.Deconstructor exposing
( Deconstructor
, alt
, bytes
, cell
, const
, cord
, float32
, float64
, int
, list
, llec
, map
, oneOf
, run
, runBytes
, sig
, string
, tape
, tar
)
@ -38,8 +42,25 @@ runBytes (Deconstructor f) bs =
(\noun -> f noun identity)
string : Deconstructor (String -> a) a
string =
const : Deconstructor (a -> a) a -> a -> Deconstructor c c
const (Deconstructor f) value =
Deconstructor
(\noun c ->
case f noun identity of
Just a ->
if a == value then
Just c
else
Nothing
Nothing ->
Nothing
)
cord : Deconstructor (String -> a) a
cord =
Deconstructor
(\x f ->
case x of
@ -52,6 +73,11 @@ string =
)
tape : Deconstructor (String -> a) a
tape =
list cord |> fmap String.concat
int : Deconstructor (Int -> a) a
int =
Deconstructor
@ -158,6 +184,16 @@ alt (Deconstructor f) (Deconstructor g) =
)
oneOf : List (Deconstructor a b) -> Deconstructor a b
oneOf l =
case l of
[] ->
Deconstructor (\_ _ -> Nothing)
x :: xs ->
alt x (oneOf xs)
tar : Deconstructor a a
tar =
Deconstructor (\_ a -> Just a)
@ -192,3 +228,8 @@ cell (Deconstructor l) (Deconstructor r) =
map : a -> Deconstructor a b -> Deconstructor (b -> c) c
map a (Deconstructor f) =
Deconstructor (\noun g -> f noun a |> Maybe.map g)
fmap : (a -> b) -> Deconstructor (a -> c) c -> Deconstructor (b -> c) c
fmap f (Deconstructor g) =
Deconstructor (\noun h -> g noun (f >> h))

View File

@ -93,6 +93,52 @@ tests =
(Bytes.fromByteValues [ 0x01, 0x1F, 0x00, 0x00, 0x20, 0x08, 0x7C, 0x00, 0x00, 0x98, 0x20 ])
)
)
, test "[8 'hi']"
(\() ->
Expect.equal
(Just ( 8, "hi" ))
(D.runBytes
(D.cell D.int D.cord |> D.map Tuple.pair)
(Bytes.fromByteValues [ 0x41, 0x10, 0x3C, 0x5A, 0x1A ])
)
)
, test "[8 \"hi\"]"
(\() ->
Expect.equal
(Just ( 8, "hi" ))
(D.runBytes
(D.cell D.int D.tape |> D.map Tuple.pair)
(Bytes.fromByteValues [ 0x41, 0x30, 0x38, 0x3A, 0x78, 0x5A ])
)
)
, describe "sum types"
[ test "[%tape \"hi\"]"
(\() ->
Expect.equal
(Just "hi")
(D.runBytes
(D.oneOf
[ D.cell (D.const D.cord "tape") D.tape
, D.cell (D.const D.cord "cord") D.cord
]
)
(Bytes.fromByteValues [ 0x01, 0x9F, 0x2E, 0x0C, 0xAE, 0x1C, 0x1C, 0x1D, 0x3C, 0x2D ])
)
)
, test "[%cord 'hi']"
(\() ->
Expect.equal
(Just "hi")
(D.runBytes
(D.oneOf
[ D.cell (D.const D.cord "tape") D.tape
, D.cell (D.const D.cord "cord") D.cord
]
)
(Bytes.fromByteValues [ 0x01, 0x7F, 0xEC, 0x4D, 0x8E, 0x0C, 0x1E, 0x2D, 0x0D ])
)
)
]
]
]