Let me first explain my understanding of why we need this monstrosity. Essentially, I want to work on lists of SymInteger
. But, AFAIU, you need to wrap a SymInteger
into a UnionM
whenever the result of an operation is not a simple value (like 2
or "a"
) and it is e.g., a condition (e.g., the result of mrgIf
).
Now, suppose we want to create a function that takes two [SymInteger]
and returns a [SymInteger]
that has the element-wise maximum of the two lists. We cannot do the following:
pickLargest :: [SymInteger] -> [SymInteger] -> [SymInteger]
-- skip simple cases
pickLargest (x:xs) (y:ys) = (mrgIf (x .> y) x y) : (sumSym xs ys)
because mrgIf
returns UnionM SymInteger
and not SymInteger
. So, we need [UnionM SymInteger]
for our functions to be generic, like so:
pickLargest :: [UnionM SymInteger] -> [UnionM SymInteger] -> [UnionM SymInteger]
-- ...
pickLargest (x:xs) (y:ys) = (mrgIf (x .> y) x y) : (pickLargest xs ys)
Now, suppose that I also want to create a function that drops an element from a list, if it exists. I can’t use symDrop because that takes a SymInteger
and not a UnionM SymInteger
. So, the following won’t work:
myVar :: [UnionM SymInteger]
myVar = pickLargest ["a", "b"] ["c", "d"]
dropOnSym = print (symDrop (head myVar) myVar)
because head myVar
has type UnionM SymInteger
(and AFAIU, it will also not work
if I want to call symDrop
on the result of symDrop
). Finally, because we don’t know the length of the resulting list, it makes sense that it needs to be wrapped in a UnionM
.
Thus, the only way to implement symListDrop I’ve found is this:
symListDrop :: UnionM [UnionM SymInteger] -> UnionM SymInteger -> UnionM [UnionM SymInteger]
symListDrop m_ser m_el = do
ser <- m_ser
case ser of
[] -> mrgReturn []
(x:_) -> mrgIf (x .== m_el)
(symListDrop m_ser m_el)
(mrgBind (symListDrop m_ser m_el) (ys -> mrgReturn (x : ys)))
which I’m afraid is just me trying really really hard… In particular, the fact that I have to unpack the UnionM
seems suspicious.
So, do you have a suggestion on how to implement this function, or alternatively, a different way that these problems are supposed to be modeled?