I notice here and in other functions in this file, we take the limbs and corresponding sizes instead of simply passing a mpz_t. This seems like unnecessary deconstructing and reconstructing of mpz_t. It also forces the Haskell code to decide on a limb size even though that is already handled by the gmp library. Is there a reason for this or can we refactor (accept/return mpz_t instead of mp_limb_t and mp_size_t)?
Well, this was an intentional design choice driven by the representation chosen for data Integer and to avoid constructing any C structs in Haskell-land and instead have the C FFI act as a facade which provides us a uniform FFI api (we actually want a mpn_*-style API; that's what we facade for here for a couple of high-level GMP operations which are currently only available w/ the less convenient mpz_t API) based on passing around limbs as Haskell-owned ByteArray#s w/ an Int# count separately (which was lateron intended to be pluggable w/ backends other than GMP but using the same common denominator FFI ABI). And if given the choice to do this kind of construction/deconstructing in Haskell or in C, I'd almost always pick the C side as it's more idiomatic to do so there. I really don't see any benefit in doing the co/denstruction in Haskell-land.
I've checked this and it makes sense.
While we are at it, the description of integer_gmp_gcdext states that this function "set s and t to coefficients satisfying x*s + y*t = g", but it only sets s (t is not returned in any way). This shouldn't block merging though.