if-instance 0.2.1.0 → 0.2.1.1
raw patch · 4 files changed
+37/−24 lines, 4 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
Files
- changelog.md +5/−0
- if-instance.cabal +12/−12
- src/Data/Constraint/If.hs +19/−11
- src/IfSat/Plugin.hs +1/−1
changelog.md view
@@ -1,3 +1,8 @@+ +# Version 0.2.1.1 (2021-08-31) + +- Minor documentation improvements. + # Version 0.2.1.0 (2021-08-31) - Require `ghc-tcplugin-api >= 0.5.1.0`.
if-instance.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: if-instance -version: 0.2.1.0 +version: 0.2.1.1 synopsis: Branch on whether a constraint is satisfied license: BSD-3-Clause build-type: Simple @@ -12,8 +12,7 @@ description: 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). + whether a constraint is satisfied (not limited to typeclass instances). Usage example: @@ -29,16 +28,17 @@ hypot = ifSat @(FMA a) withFMA withoutFMA where withFMA :: FMA a => a -> a -> a - withFMA a b = + withFMA x y = let - h = sqrt $ fma a a (b * b) + h = sqrt $ fma x x (y * y) h² = h * h - a² = a * a - x = fma (-b) b (h² - a²) + fma h h (-h²) - fma a a (-a²) + x² = x * x + u = fma (-y) y (h² - x²) + fma h h (-h²) - fma x x (-x²) in - h - x / ( 2 * h ) + h - u / ( 2 * h ) withoutFMA :: a -> a -> a - withoutFMA a b = sqrt ( a * a + b * b ) + withoutFMA x y = sqrt ( x * x + y * y ) + @ Here we select between two ways of computing the hypotenuse function @@ -46,8 +46,8 @@ @ 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. + 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 @@ -60,7 +60,7 @@ build-depends: base - >= 4.14.0 && < 4.18, + >= 4.15.0 && < 4.18, ghc >= 9.0 && < 9.6,
src/Data/Constraint/If.hs view
@@ -19,7 +19,10 @@ then the @yes@ branch is selected, which has access to the @ct@ constraint; - otherwise, the fallback branch @no@ is selected. -To use this, you will also need to enable the corresponding 'IfSat.Plugin.plugin', +This module also provides the type family @'IsSat' :: Constraint -> Bool@, which, when reduced, +will check whether the constraint provided as an argument is satisfied. + +To use this module, you will also need to enable the corresponding 'IfSat.Plugin.plugin', by adding @\{\-\# OPTIONS_GHC -fplugin=IfSat.Plugin \#\-\}@ to the header of your module. @@ -83,24 +86,29 @@ >>> test1 not "<<function>>" -In this example, to typecheck @test1@ we need to solve @IfSat (Show (Bool -> Bool))@. +In this example, to typecheck @test1@ we need to solve @IfSat (Show (Bool -> Bool))@ +inside module @M1@. As no instance for @Show (Bool -> Bool)@ is available in @M1@, we pick the second branch, resulting in @"\<\<function\>\>"@. >>> test2 not "<<function>>" -In this example, we must solve @IfSat (Show (a -> a))@. There is no such instance in @M2@, -so we pick the second branch. +In this example, we must solve @IfSat (Show (a -> a))@ within @M2@. There is no such instance in @M2@, +so we pick the second branch. +It doesn't matter that we are calling @test2@ with a function of type +@Bool -> Bool@: we had to solve @IfSat (Show (a -> a))@ when type-checking +the type signature of @test2@. >>> test3 not "[True, False]" ->>> showFun not -"[True, False]" +In this last example, we must solve @IfSat (Show (Bool -> Bool))@, but as we're in @M2@, +such an instance is available, so we choose the first branch. -In these last two examples, we must solve @IfSat (Show (Bool -> Bool))@. -Such an instance is in scope in @M2@, so we choose the first branch. +Note in particular that @test1@ and @test3@ have the exact same definition (same type signature, +same body), but produce a different result. This is because the satisfiability check happens in +different contexts. -} module Data.Constraint.If @@ -125,10 +133,10 @@ -- Note: the selection happens at the point in the code where the @IfSat ct@ -- constraint is solved. ifSat :: ( ( IsSat ct ~ True, ct ) => r ) - -> ( IsSat ct ~ False => r) - -> r + -> ( IsSat ct ~ False => r ) + -> r --- | @IsSat ct@ returns @True@ if @ct@ is satified, and @False@ otherwise. +-- | @IsSat ct@ returns @True@ if @ct@ is satisfied, and @False@ otherwise. -- -- The satisfiability check occurs at the moment of type-family reduction. type IsSat :: Constraint -> Bool
src/IfSat/Plugin.hs view
@@ -49,7 +49,7 @@ -- Plugin definition. -- | A type-checking plugin that solves @MyCt ct@ constraints. --- Theis allows users to branch on whether @ct@ is satisfied. +-- This allows users to branch on whether @ct@ is satisfied. -- -- To use this plugin, add @{-# OPTIONS_GHC -fplugin=IfSat.Plugin #-}@ -- to your module header.