if-instance

Version 0.5.2.0 revision 0 uploaded by sheaf.

Package meta

Synopsis
Branch on whether a constraint is satisfied
Description

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.

Author
Sam Derbyshire
Bug reports
n/a
Category
Type System, Plugin
Copyright
2021 Sam Derbyshire
Homepage
https://github.com/sheaf/if-instance
Maintainer
Sam Derbyshire
Package URL
n/a
Stability
n/a

Components