git @ Cat's Eye Technologies Dipple / master haskell / mconcatenative.hs
master

Tree @master (Download .tar.gz)

mconcatenative.hs @masterraw · history · blame

-- SPDX-FileCopyrightText: Chris Pressey, the original author of this work, has dedicated it to the public domain.
-- For more information, please refer to <https://unlicense.org/>
-- SPDX-License-Identifier: Unlicense

--
-- A simple way to evaluate a purely concatenative language is to
-- to sequentially compose the list of functions that the program represents
-- into a single function, and then apply that function.
--
-- Can we use mconcat to do this?  Yes, if we treat them as endofunctors.
--

import Data.Monoid

push n s = (n:s)
add (a:b:s) = (a+b:s)
divide (a:b:s) = (a `div` b:s)
swap (a:b:s) = (b:a:s)
pop (a:s) = s

ops = [(push 6), (push 6), (add), (push 3), (swap), (divide)]

-- fold functions into a single function and apply it (try "run []")
frun = foldl (flip (.)) id ops

-- mconcat Endos into a single Endo and appEndo it (try "erun []")
erun = appEndo $ getDual $ mconcat $ map (Dual . Endo) ops