úÎC}A`$      !"#None0123457DR[isomorphic to:  ,data Sexp_ a = Atom_ a | List_ [Sexp_ a] Wwhen you only care about lists (e.g. to interface with other s-expression libraries). a heterogenous list.a  ?http://en.wikipedia.org/wiki/Common_Lisp#The_function_namespaceLisp-2 S-expression, where:f is the function namespacea is the atom namespaceyou could define type Lisp1 a = Sexp a a. with some caveats: f is ignored by $ic methods like plate doesn't reach the f , even when f ~ a , as the %' instance is manual, not automatic via Data.the  case is just a specialized  (), but easier to work with than:Sexp (Maybe f) [Sexp f a] (where Nothing would represent )forcing each concrete f, to hold a unit case (which would represent ) examples: E'toList' (List [Atom "f",Atom "x",List [Atom "g",Atom "y"],Atom "z"])["f","x","g","y","z"]:{let doubleSexp e = do x <- e" listSexp [x,x]:} :doubleSexp (List [Atom "f", Sexp () [Atom "a", Atom "b"]])[List [List [Atom "f",Atom "f"],Sexp () [List [Atom "a",Atom "a"],List [Atom "b",Atom "b"]]] Rdata ByteSexp = Atom ByteString | List [ByteSexp] bytesexp2sexp :: ByteSexp ->  ByteString bytesexp2sexp = 3 $ case Atom s -> Left s List es -> Right es   pureSexp =  :set -XOverloadedStrings"x" :: Sexp f String Atom "x"  definitions:  & =  '(>>=)' =  proofs of laws:left-inverse(1): join . return = id :join (return m) joinSexp (pureSexp m) joinSexp (Atom m) m left-inverse(2): join . fmap return = idE(the Sexp case is elided, the steps being identical to the List case) ÿÿjoin (fmap return m) joinSexp (fmap pureSexp m) joinSexp (fmap Atom m) -- case analysis case m of Atom x -> joinSexp (Atom (Atom x)) -- by definition of joinSexp Atom x List ms -> joinSexp (List (fmap (fmap Atom) ms) -- by definition of joinSexp List (fmap joinSexp (fmap (fmap Atom) ms)) -- functor composition List (fmap (joinSexp . fmap Atom) ms) List (fmap (join . fmap return) ms) -- by induction List (fmap id ms) -- functor identity List ms -- both cases are identity m where: ƒfmap f = case Atom x -> f x List ms -> List (fmap (fmap f) ms) join = case Atom x -> x List ms -> List (fmap joinSexp ms) associativity(3): join . join = join . fmap join TODO default instance via the $ subclass.  emptySexp =  []'appendSexp (Atom "f") (List [Atom "x"])List [Atom "f",Atom "x"]6refines any Sexp to a list, which can be given to the . fold over an sexp. Ui.e. strictly evaluate a sexp ("all the way") to an atom, within any monadic context.6data ArithFunc = Add | Multiply | Negate deriving ShowNlet badArith = Sexp Negate [Atom 1, Atom 2, Atom 3] :: Sexp ArithFunc Integerulet goodArith = Sexp Add [Sexp Multiply [], Sexp Negate [Atom (10::Integer)], Sexp Multiply [Atom 2, Atom 3, Atom 4]]:set -XLambdaCase:{ let evalArith = \case" Add -> \case4 xs -> Just [sum xs]" Multiply -> \case8 xs -> Just [product xs]" Negate -> \case7 [x] -> Just [negate x] / _ -> Nothing :}DevalSplatSexp (flip evalArith) (fmap (:[]) badArith) -- wrong arityNothing QevalSplatSexp (flip evalArith) (fmap (:[]) goodArith) -- (+ (*) (- 10) (* 2 3 4)) Just [15] specializing, as above,  (m ~ Maybe), (b ~ [Integer]), (g ~ ArithFunc): mevalSplatSexp :: ([Integer] -> ArithFunc -> Maybe [Integer]) -> (Sexp ArithFunc [Integer] -> Maybe [Integer]) evalSplatSexp apply =  ( 'pure'.'fold' ) (apply.')when a Sexp's atoms are (bal ("list-like"), after evaluating some expressions into atoms, we can "splat" them back together. splatList takes:  an evaluator evaland a list of s-expressions es to evaluate in sequence.inject a list of atoms. listSexp [1,2,3]List [Atom 1,Atom 2,Atom 3]   None01!!!!None01["#"#"#"#)      !"#$%&'()*+,'(-'./'(01)s-expression-0.0.0-G3iGEh3gocX9fdzOVwuTpc Data.SexpData.Sexp.ExampleData.Sexp.MainSexp_SexpAtomListtoSexppureSexpbindSexpjoinSexp$fIsStringSexp $fPlatedSexp $fMonadSexp$fApplicativeSexp $fShowSexp $fReadSexp$fEqSexp $fOrdSexp $fFunctorSexp$fFoldableSexp$fTraversableSexp $fDataSexp $fGenericSexp emptySexp appendSexp toSexpListevalSexp evalSplatSexp splatSexpListlistSexp D:R:ItemSexp $fIsListSexp $fMonoidSexp$fSemigroupSexp exampleSexpmainmainWithbaseGHC.BaseMonad"lens-4.15.2-7NfXuU5AnOD65llKMmK4xMControl.Lens.PlatedPlatedreturn Data.FoldablefoldMonoid