We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.
Carriage/Carriage.hs
Jump to navigation
Jump to search
Quick and dirty implementation of Carriage in Haskell. Program might not explode under every condition it is supposed to explode (but please do consider every error to be an explosion, not just BOOM). Runs the two examples given in the article.
explode = error "BOOM"
data Elem = Int Integer
| Fn ([Elem] -> [Elem])
| Sym Char
instance Show Elem where
show (Int i) = show i
show (Fn _) = "<fn>"
show (Sym c) = show c
pop (e:s) = (e, s)
push s e = (e:s)
pick 0 ((Sym _):_) = explode
pick 0 (e:_) = e
pick n (_:s) = pick (n-1) s
slice _ 0 _ = []
slice p k s = slice' p (reverse s)
where
slice' 0 s = take (fromIntegral k) s
slice' n (_:s) = slice' (n-1) s
ci " " = id
ci "1" = \s -> push s $ Int 1
ci "$" = snd . pop
ci "#" = \s -> push s $ Int $ fromIntegral $ length s
ci "~" = (\s ->
let
(Int a, s') = pop(s)
in
push s' $ pick a s')
ci "\\" = (\s ->
let
(a, s') = pop(s)
(b, s'') = pop(s')
in
push (push s'' a) b)
ci "+" = (\s ->
let
(Int a, s') = pop(s)
(Int b, s'') = pop(s')
in
push s'' $ Int (a + b))
ci "-" = (\s ->
let
(Int a, s') = pop(s)
(Int b, s'') = pop(s')
in
push s'' $ Int (b - a))
ci "@" = (\s ->
let
(Int k, s') = pop(s)
(Int p, s'') = pop(s')
fn = ci $ map (\(Sym c) -> c) $ slice p k s''
in
push s'' (Fn fn))
ci "!" = \s -> let (Fn f, s') = pop(s) in f s'
ci [] = id
ci [_] = explode
ci (sym:rest) = \x -> (ci rest) ((ci [sym]) x)
di = reverse . map (\x -> Sym x) . filter (\x -> x /= ' ')
run prog = (ci prog) (di prog)