@hackage if-instance0.1.0.0
Branch on whether a constraint is satisfied
Deprecated
Dependencies (6)
- base >=4.14.0 && <4.18
- ghc >=8.10 && <9.6
- ghc-tcplugin-api >=0.5.0.0 && <0.6 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, despite the name of the library).
Usage example:
{-# OPTIONS_GHC -fplugin=IfCt.Plugin #-}
module MyModule where
import Data.Constraint.If ( IfCt(ifCt) )
hypot :: forall a. ( Floating a, IfCt (FMA a) ) => a -> a -> a
hypot = ifCt @(FMA a) withFMA withoutFMA
where
withFMA :: FMA a => a -> a -> a
withFMA a b =
let
h = sqrt $ fma a a (b * b)
h² = h * h
a² = a * a
x = fma (-b) b (h² - a²) + fma h h (-h²) - fma a a (-a²)
in
h - x / ( 2 * h )
withoutFMA :: a -> a -> a
withoutFMA a b = sqrt ( a * a + b * b )
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 \ a b c -> ( a * b ) + c in a single instruction,
providing stronger guarantees about precision of the resul.
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.