translateUnOp :: VirtualSegmentAlgebra a
              => VSL.UnOp TExpr TExpr
              -> Res (VSLDVec a) (VSLRVec a)
              -> B.Build a (Res (VSLDVec a) (VSLRVec a))
translateUnOp unop c = case unop of
    VSL.Fold a           -> fromDVec <$> vecFold a (toDVec c)
    VSL.Distinct         -> fromDVec <$> vecDistinct (toDVec c)
    VSL.Number           -> fromDVec <$> vecNumber (toDVec c)
    VSL.MergeMap         -> fromRVec <$> vecMergeMap (toDVec c)
    VSL.WinFun  (a, w)   -> fromDVec <$> vecWinFun a w (toDVec c)
    VSL.Segment          -> fromDVec <$> vecSegment (toDVec c)
    VSL.Unsegment        -> fromDVec <$> vecUnsegment (toDVec c)
    VSL.Select e         -> do
        (d, r) <- vecSelect e (toDVec c)
        return $ RLPair (fromDVec d) (fromRVec r)
    VSL.Sort e         -> do
        (d, p) <- vecSort e (toDVec c)
        return $ RLPair (fromDVec d) (fromRVec p)
    VSL.Group es -> do
        (qo, qi, p) <- vecGroup es (toDVec c)
        return $ RTriple (fromDVec qo) (fromDVec qi) (fromRVec p)
    VSL.Project cols -> fromDVec <$> vecProject cols (toDVec c)
    VSL.Reverse      -> do
        (d, p) <- vecReverse (toDVec c)
        return $ RLPair (fromDVec d) (fromRVec p)
    VSL.GroupAggr (g, as) -> fromDVec <$> vecGroupAggr g as (toDVec c)

    VSL.UnitMap -> fromRVec <$> vecUnitMap (toDVec c)
    VSL.UpdateUnit -> fromRVec <$> vecUpdateUnit (toRVec c)

    VSL.R1            -> case c of
        (RLPair c1 _)     -> return c1
        (RTriple c1 _ _) -> return c1
        _                -> error "R1: Not a tuple"
    VSL.R2            -> case c of
        (RLPair _ c2)     -> return c2
        (RTriple _ c2 _) -> return c2
        _                -> error "R2: Not a tuple"
    VSL.R3            -> case c of
        (RTriple _ _ c3) -> return c3
        _                -> error "R3: Not a tuple"
translateUnOp :: VirtualSegmentAlgebra a
              => VSL.UnOp TExpr TExpr
              -> Res (VSLDVec a) (VSLRVec a)
              -> B.Build a (Res (VSLDVec a) (VSLRVec a))
translateUnOp unop c = case unop of
    VSL.Fold a           -> fromDVec <$> vecFold a (toDVec c)
    VSL.Distinct         -> fromDVec <$> vecDistinct (toDVec c)
    VSL.Number           -> fromDVec <$> vecNumber (toDVec c)
    VSL.MergeMap         -> fromRVec <$> vecMergeMap (toDVec c)
    VSL.WinFun  (a, w)   -> fromDVec <$> vecWinFun a w (toDVec c)
    VSL.Segment          -> fromDVec <$> vecSegment (toDVec c)
    VSL.Unsegment        -> fromDVec <$> vecUnsegment (toDVec c)
    VSL.Select e         -> do
        (d, r) <- vecSelect e (toDVec c)
        return $ RLPair (fromDVec d) (fromRVec r)
    VSL.Sort e         -> do
        (d, p) <- vecSort e (toDVec c)
        return $ RLPair (fromDVec d) (fromRVec p)
    VSL.Group es -> do
        (qo, qi, p) <- vecGroup es (toDVec c)
        return $ RTriple (fromDVec qo) (fromDVec qi) (fromRVec p)
    VSL.Project cols -> fromDVec <$> vecProject cols (toDVec c)
    VSL.Reverse      -> do
        (d, p) <- vecReverse (toDVec c)
        return $ RLPair (fromDVec d) (fromRVec p)
    VSL.GroupAggr (g, as) -> fromDVec <$> vecGroupAggr g as (toDVec c)

    VSL.UnitMap -> fromRVec <$> vecUnitMap (toDVec c)
    VSL.UpdateUnit -> fromRVec <$> vecUpdateUnit (toRVec c)

    VSL.R1            -> case c of
        (RLPair c1 _)     -> return c1
        (RTriple c1 _ _) -> return c1
        _                -> error "R1: Not a tuple"
    VSL.R2            -> case c of
        (RLPair _ c2)     -> return c2
        (RTriple _ c2 _) -> return c2
        _                -> error "R2: Not a tuple"
    VSL.R3            -> case c of
        (RTriple _ _ c3) -> return c3
        _                -> error "R3: Not a tuple"
translateUnOp unop c = case unop of
    VSL.Fold a           -> fromDVec <$> vecFold a (toDVec c)
    VSL.Distinct         -> fromDVec <$> vecDistinct (toDVec c)
    VSL.Number           -> fromDVec <$> vecNumber (toDVec c)
    VSL.MergeMap         -> fromRVec <$> vecMergeMap (toDVec c)
    VSL.WinFun  (a, w)   -> fromDVec <$> vecWinFun a w (toDVec c)
    VSL.Segment          -> fromDVec <$> vecSegment (toDVec c)
    VSL.Unsegment        -> fromDVec <$> vecUnsegment (toDVec c)
    VSL.Select e         -> do
        (d, r) <- vecSelect e (toDVec c)
        return $ RLPair (fromDVec d) (fromRVec r)
    VSL.Sort e         -> do
        (d, p) <- vecSort e (toDVec c)
        return $ RLPair (fromDVec d) (fromRVec p)
    VSL.Group es -> do
        (qo, qi, p) <- vecGroup es (toDVec c)
        return $ RTriple (fromDVec qo) (fromDVec qi) (fromRVec p)
    VSL.Project cols -> fromDVec <$> vecProject cols (toDVec c)
    VSL.Reverse      -> do
        (d, p) <- vecReverse (toDVec c)
        return $ RLPair (fromDVec d) (fromRVec p)
    VSL.GroupAggr (g, as) -> fromDVec <$> vecGroupAggr g as (toDVec c)

    VSL.UnitMap -> fromRVec <$> vecUnitMap (toDVec c)
    VSL.UpdateUnit -> fromRVec <$> vecUpdateUnit (toRVec c)

    VSL.R1            -> case c of
        (RLPair c1 _)     -> return c1
        (RTriple c1 _ _) -> return c1
        _                -> error "R1: Not a tuple"
    VSL.R2            -> case c of
        (RLPair _ c2)     -> return c2
        (RTriple _ c2 _) -> return c2
        _                -> error "R2: Not a tuple"
    VSL.R3            -> case c of
        (RTriple _ _ c3) -> return c3
        _                -> error "R3: Not a tuple"