{-# LANGUAGE OverloadedStrings #-}
module SMR.Prim.Op.List where
import SMR.Core.Exp
import SMR.Prim.Op.Base
primOpsList :: [PrimEval s Prim w]
primOpsList
= [ primOpListCons, primOpListUncons
, primOpListSnoc, primOpListUnsnoc
, primOpListAppend ]
primOpListCons :: PrimEval s Prim w
primOpListCons
= PrimEval
(PrimOp "list-cons")
"add an element to the front of a list"
[PExp, PVal] fn'
where
fn' _world as0
| Just (x1, as1) <- takeArgExp as0
, Just (XApp tag@(XRef (RPrm PrimTagList)) xs, [])
<- takeArgExp as1
= return $ Just $ XApp tag (x1 : xs)
fn' _world _
= return $ Nothing
primOpListUncons :: PrimEval s Prim w
primOpListUncons
= PrimEval
(PrimOp "list-uncons")
"split an element from the front of a list"
[PVal, PExp] fn'
where
fn' _world as0
| Just (XApp tag@(XRef (RPrm PrimTagList)) xx, as1)
<- takeArgExp as0
, Just (x2, []) <- takeArgExp as1
= case xx of
x1 : xs -> return $ Just $ XApp x2 [x1, XApp tag xs]
[] -> return $ Nothing
fn' _world _
= return $ Nothing
primOpListSnoc :: PrimEval s Prim w
primOpListSnoc
= PrimEval
(PrimOp "list-snoc")
"add an element to the end of a list"
[PVal, PExp] fn'
where
fn' _world as0
| Just (XApp tag@(XRef (RPrm PrimTagList)) xs, as1)
<- takeArgExp as0
, Just (x1, []) <- takeArgExp as1
= return $ Just $ XApp tag (xs ++ [x1])
fn' _world _
= return $ Nothing
primOpListUnsnoc :: PrimEval s Prim w
primOpListUnsnoc
= PrimEval
(PrimOp "list-unsnoc")
"split an element from the end of a list"
[PVal, PExp] fn'
where
fn' _world as0
| Just (XApp tag@(XRef (RPrm PrimTagList)) xx, as1)
<- takeArgExp as0
, Just (x2, []) <- takeArgExp as1
= case reverse xx of
x1 : xs -> return $ Just $ XApp x2 [XApp tag (reverse xs), x1]
[] -> return $ Nothing
fn' _world _
= return $ Nothing
primOpListAppend :: PrimEval s Prim w
primOpListAppend
= PrimEval
(PrimOp "list-append")
"append two lists"
[PVal, PVal] fn'
where
fn' _world as0
| Just (XApp (XRef (RPrm PrimTagList)) xs1, as1)
<- takeArgExp as0
, Just (XApp tag@(XRef (RPrm PrimTagList)) xs2, [])
<- takeArgExp as1
= return $ Just (XApp tag (xs1 ++ xs2))
fn' _world _
= return $ Nothing