@hackage if-instance0.6.0.0
Branch on whether a constraint is satisfied
Installation
Dependencies (7)
- base >=4.15.0 && <4.22
- ghc >=9.0 && <9.14
- ghc-tcplugin-api >=0.13 && <0.17
- transformers >=0.5.6.2 && <0.7 Show all…
Dependents (0)
This library provides a mechanism that can be used to branch on whether a constraint is satisfied (not limited to typeclass instances).
Usage example:
{-# OPTIONS_GHC -fplugin=IfSat.Plugin #-}
module MyModule where
import Data.Constraint.If ( IfSat(ifSat) )
hypot :: forall a. ( Floating a, IfSat (FMA a) ) => a -> a -> a
hypot = ifSat @(FMA a) withFMA withoutFMA
where
withFMA :: FMA a => a -> a -> a
withFMA x y =
let
h = sqrt $ fma x x (y * y)
h² = h * h
x² = x * x
u = fma (-y) y (h² - x²) + fma h h (-h²) - fma x x (-x²)
in
h - u / ( 2 * h )
withoutFMA :: a -> a -> a
withoutFMA x y = sqrt ( x * x + y * y )
Here we select between two ways of computing the hypotenuse function based on whether we have access to the fused multiply-add operation
fma :: FMA a => a -> a -> a -> a
which computes \ x y z -> ( x * y ) + z in a single instruction,
providing stronger guarantees about precision of the result.
A call of the form hypot @MyNumberType will either use the robust withFMA
function when an FMA MyNumberType instance is available, or will fallback
to the simple withoutFMA implementation when no such instance can be found.