translateBinOp :: VirtualSegmentAlgebra a
               => VSL.BinOp TExpr
               -> Res (VSLDVec a) (VSLRVec a)
               -> Res (VSLDVec a) (VSLRVec a)
               -> B.Build a (Res (VSLDVec a) (VSLRVec a))
translateBinOp b c1 c2 = case b of
    VSL.ReplicateSeg -> do
        (v, p) <- vecReplicateSeg (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec p)

    VSL.ReplicateScalar -> do
        (v, p) <- vecReplicateScalar (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec p)

    VSL.Materialize -> do
        (v, p) <- vecMaterialize (toRVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec p)

    VSL.UnboxSng -> do
        (v, k) <- vecUnboxSng (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec k)

    VSL.Append -> do
        (v, r1, r2) <- vecAppend (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec r1) (fromRVec r2)


    VSL.Align -> fromDVec <$> vecAlign (toDVec c1) (toDVec c2)

    VSL.Zip -> do
        (v, r1 ,r2) <- vecZip (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec r1) (fromRVec r2)

    VSL.CartProduct -> do
        (v, p1, p2) <- vecCartProduct (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec p1) (fromRVec p2)

    VSL.ThetaJoin (l1, l2, p) -> do
        (v, p1, p2) <- vecThetaJoin l1 l2 p (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec p1) (fromRVec p2)

    VSL.NestJoin (l1, l2, p) -> do
        (v, p1, p2) <- vecNestJoin l1 l2 p (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec p1) (fromRVec p2)

    VSL.GroupJoin (l1, l2, p, as) -> fromDVec <$> vecGroupJoin l1 l2 p as (toDVec c1) (toDVec c2)

    VSL.SemiJoin (l1, l2, p) -> do
        (v, r) <- vecSemiJoin l1 l2 p (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec r)

    VSL.AntiJoin (l1, l2, p) -> do
        (v, r) <- vecAntiJoin l1 l2 p (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec r)

    VSL.UnboxDefault vs -> do
        (v, r) <- vecUnboxDefault vs (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec r)

    VSL.UpdateMap -> fromRVec <$> vecUpdateMap (toRVec c1) (toRVec c2)
translateBinOp :: VirtualSegmentAlgebra a
               => VSL.BinOp TExpr
               -> Res (VSLDVec a) (VSLRVec a)
               -> Res (VSLDVec a) (VSLRVec a)
               -> B.Build a (Res (VSLDVec a) (VSLRVec a))
translateBinOp b c1 c2 = case b of
    VSL.ReplicateSeg -> do
        (v, p) <- vecReplicateSeg (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec p)

    VSL.ReplicateScalar -> do
        (v, p) <- vecReplicateScalar (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec p)

    VSL.Materialize -> do
        (v, p) <- vecMaterialize (toRVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec p)

    VSL.UnboxSng -> do
        (v, k) <- vecUnboxSng (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec k)

    VSL.Append -> do
        (v, r1, r2) <- vecAppend (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec r1) (fromRVec r2)


    VSL.Align -> fromDVec <$> vecAlign (toDVec c1) (toDVec c2)

    VSL.Zip -> do
        (v, r1 ,r2) <- vecZip (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec r1) (fromRVec r2)

    VSL.CartProduct -> do
        (v, p1, p2) <- vecCartProduct (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec p1) (fromRVec p2)

    VSL.ThetaJoin (l1, l2, p) -> do
        (v, p1, p2) <- vecThetaJoin l1 l2 p (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec p1) (fromRVec p2)

    VSL.NestJoin (l1, l2, p) -> do
        (v, p1, p2) <- vecNestJoin l1 l2 p (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec p1) (fromRVec p2)

    VSL.GroupJoin (l1, l2, p, as) -> fromDVec <$> vecGroupJoin l1 l2 p as (toDVec c1) (toDVec c2)

    VSL.SemiJoin (l1, l2, p) -> do
        (v, r) <- vecSemiJoin l1 l2 p (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec r)

    VSL.AntiJoin (l1, l2, p) -> do
        (v, r) <- vecAntiJoin l1 l2 p (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec r)

    VSL.UnboxDefault vs -> do
        (v, r) <- vecUnboxDefault vs (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec r)

    VSL.UpdateMap -> fromRVec <$> vecUpdateMap (toRVec c1) (toRVec c2)
translateBinOp b c1 c2 = case b of
    VSL.ReplicateSeg -> do
        (v, p) <- vecReplicateSeg (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec p)

    VSL.ReplicateScalar -> do
        (v, p) <- vecReplicateScalar (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec p)

    VSL.Materialize -> do
        (v, p) <- vecMaterialize (toRVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec p)

    VSL.UnboxSng -> do
        (v, k) <- vecUnboxSng (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec k)

    VSL.Append -> do
        (v, r1, r2) <- vecAppend (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec r1) (fromRVec r2)


    VSL.Align -> fromDVec <$> vecAlign (toDVec c1) (toDVec c2)

    VSL.Zip -> do
        (v, r1 ,r2) <- vecZip (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec r1) (fromRVec r2)

    VSL.CartProduct -> do
        (v, p1, p2) <- vecCartProduct (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec p1) (fromRVec p2)

    VSL.ThetaJoin (l1, l2, p) -> do
        (v, p1, p2) <- vecThetaJoin l1 l2 p (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec p1) (fromRVec p2)

    VSL.NestJoin (l1, l2, p) -> do
        (v, p1, p2) <- vecNestJoin l1 l2 p (toDVec c1) (toDVec c2)
        return $ RTriple (fromDVec v) (fromRVec p1) (fromRVec p2)

    VSL.GroupJoin (l1, l2, p, as) -> fromDVec <$> vecGroupJoin l1 l2 p as (toDVec c1) (toDVec c2)

    VSL.SemiJoin (l1, l2, p) -> do
        (v, r) <- vecSemiJoin l1 l2 p (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec r)

    VSL.AntiJoin (l1, l2, p) -> do
        (v, r) <- vecAntiJoin l1 l2 p (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec r)

    VSL.UnboxDefault vs -> do
        (v, r) <- vecUnboxDefault vs (toDVec c1) (toDVec c2)
        return $ RLPair (fromDVec v) (fromRVec r)

    VSL.UpdateMap -> fromRVec <$> vecUpdateMap (toRVec c1) (toRVec c2)