diff options
-rw-r--r-- | samples/fun/minibruijn.bruijn | 33 | ||||
-rw-r--r-- | std/Generic/Monad.bruijn | 29 | ||||
-rw-r--r-- | std/Monad/Generic.bruijn | 16 | ||||
-rw-r--r-- | std/Monad/Parser.bruijn | 9 |
4 files changed, 69 insertions, 18 deletions
diff --git a/samples/fun/minibruijn.bruijn b/samples/fun/minibruijn.bruijn new file mode 100644 index 0000000..1364983 --- /dev/null +++ b/samples/fun/minibruijn.bruijn @@ -0,0 +1,33 @@ +# MIT License, Copyright (c) 2024 Marvin Borner + +:import std/Char C +:import std/Combinator . +:import std/List . +:import std/Meta M +:import std/Monad/Parser . +:import std/Number/Conversion O +:import std/Result R + +# meta encoding uses Church numerals instead of binary! +char→number (\C.sub '0') → O.binary→unary + +identifier satisfy (c ∘ C.space?) + +spaces many (satisfy C.space?) + +newlines some (satisfy (C.eq? '\n')) + +parens between (char '(') (char ')') + +number char→number <$> (satisfy C.numeric?) + +term y [(foldl1 M.app) <$> (some (spaces *> singleton <* spaces))] + singleton abs <|> idx <|> (parens 0) + abs M.abs <$> (between (char '[') (char ']') 0) + idx M.idx <$> number + +block identifier <*> term + +program block >>= newlines + +main (M.eval <$> term) → [0 i i] diff --git a/std/Generic/Monad.bruijn b/std/Generic/Monad.bruijn new file mode 100644 index 0000000..9e6c5d3 --- /dev/null +++ b/std/Generic/Monad.bruijn @@ -0,0 +1,29 @@ +# MIT License, Copyright (c) 2024 Marvin Borner +# for now, monads, functors, applicative, etc are all in here.. + +# TODO: more monad interface + +:import std/List L + +liftA map ⧗ (a → b) → (M a) → (M b) + +liftA2 ap ∘∘ map ⧗ (a → b → c) → (M a) → (M b) → (M c) + +liftA3 [[[[(liftA2 3 2 1) <*> 0]]]] ⧗ (a → b → c → d) → (M a) → (M b) → (M c) → (M d) + +…<$… map ∘ k ⧗ a → (M b) → (M a) + +…*>… [[(i <$ 1) <*> 0]] ⧗ (M a) → (M b) → (M b) + +…<*… liftA2 k ⧗ (M a) → (M b) → (M a) + +# TODO: traverse, sequence +# in parser: string = traverse char! + +some [y [liftA2 L.cons 1 many]] ⧗ (M a) → (M (List a)) + many 0 <|> (pure L.empty) + +many [y [some <|> (pure L.empty)]] ⧗ (M a) → (M (List a)) + some liftA2 L.cons 1 0 + +between [[[2 *> 0 <* 1]]] ⧗ (M a) → (M a) → (M a) → (M a) diff --git a/std/Monad/Generic.bruijn b/std/Monad/Generic.bruijn deleted file mode 100644 index 619ecc3..0000000 --- a/std/Monad/Generic.bruijn +++ /dev/null @@ -1,16 +0,0 @@ -# MIT License, Copyright (c) 2024 Marvin Borner -# for now, monads, functors, applicative, etc are all in here.. - -# TODO: more monad interface - -liftA map ⧗ (a → b) → (f a) → (f b) - -liftA2 ap ∘∘ map ⧗ (a → b → c) → (f a) → (f b) → (f c) - -liftA3 [[[[(liftA2 3 2 1) <*> 0]]]] ⧗ (a → b → c → d) → (f a) → (f b) → (f c) → (f d) - -…<$… map ∘ k ⧗ a → (f b) → (f a) - -…*>… [[(i <$ 1) <*> 0]] ⧗ (f a) → (f b) → (f b) - -…<*… liftA2 k ⧗ (f a) → (f b) → (f a) diff --git a/std/Monad/Parser.bruijn b/std/Monad/Parser.bruijn index e11b662..c6b53a3 100644 --- a/std/Monad/Parser.bruijn +++ b/std/Monad/Parser.bruijn @@ -1,15 +1,18 @@ # MIT License, Copyright (c) 2024 Marvin Borner +# see samples/fun/minibruijn for example usage :import std/List . :import std/Combinator . :import std/Char C :import std/Result R +# TODO: don't just use strings for errors + error-unexpected ["unexpected symbol " ++ 0] ⧗ Error error-end-of-input "end of input" ⧗ Error -compose [[1 ++ " or " ++ 0]] ⧗ Error → Error → Error +compose [[C.?eq? 1 0 0 (1 ++ " or " ++ 0)]] ⧗ Error → Error → Error satisfy [[0 [[[go]]] end]] ⧗ (a → Boolean) → (Parser a) go 4 2 (R.ok (2 : 1)) (R.err (error-unexpected {}2)) @@ -62,7 +65,9 @@ alt [[[2 0 R.ok err]]] ⧗ (Parser a) → (Parser a) → (Parser a) # most relevant functions are defined - we can now derive from Generic/Monad! # # =========================================================================== # -:input std/Monad/Generic +:input std/Generic/Monad :test (k <$ (string "ab") "abc") (R.ok (k : "c")) :test ((char '{') *> (string "wow") <* (char '}') "{wow}{owo}") (R.ok ("wow" : "{owo}")) + +between [[[2 *> 0 <* 1]]] ⧗ (Parser a) → (Parser a) → (Parser a) |