opCreate :: Storable t => Bool
            -- ^ Whether the operation is commutative
            -> (FunPtr (Ptr t -> Ptr t -> Ptr CInt -> Ptr Datatype -> IO ()))
            {- ^ Pointer to function that accepts, in order:

            * @invec@, pointer to first input vector

            * @inoutvec@, pointer to second input vector, which is also the output vector

            * @len@, pointer to length of both vectors

            * @datatype@, pointer to 'Datatype' of elements in both vectors
            -}
            -> IO Operation -- ^ Handle to the created user-defined operation
opCreate commute f = do
  Internal.opCreate (castFunPtr f) commute
opCreate :: Storable t => Bool
            -- ^ Whether the operation is commutative
            -> (FunPtr (Ptr t -> Ptr t -> Ptr CInt -> Ptr Datatype -> IO ()))
            {- ^ Pointer to function that accepts, in order:

            * @invec@, pointer to first input vector

            * @inoutvec@, pointer to second input vector, which is also the output vector

            * @len@, pointer to length of both vectors

            * @datatype@, pointer to 'Datatype' of elements in both vectors
            -}
            -> IO Operation
opCreate commute f = do
  Internal.opCreate (castFunPtr f) commute
opCreate commute f = do
  Internal.opCreate (castFunPtr f) commute