Skip to content

Commit

Permalink
[#265] Make SuperComposition less brittle
Browse files Browse the repository at this point in the history
* Use overlapping instances instead of incoherent ones. Fixes #265.

* Make the first argument of `...` a function unconditionally, before
  instance selection. This can theoretically improve inference slightly,
  though it probably doesn't have much impact in practice.
  • Loading branch information
treeowl committed May 9, 2022
1 parent 86b30df commit 4791828
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Unreleased
=====

* [#265](https://github.com/serokell/universum/issues/265):
Make `SuperComposition` inference less brittle, and give it four
type parameters.

* [#252](https://github.com/serokell/universum/pull/252):
Remove `Option` re-export. Use `Maybe` instead.

Expand Down
2 changes: 1 addition & 1 deletion benchmark/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ bgroupSuperComposition = bgroup "(...)"
where
super10 :: [()] -> Bool
super10 = null
... ((: []) ... Unsafe.head ... pure ... Unsafe.head
... ((: []) ... Unsafe.head ... (:[]) ... Unsafe.head
... (: [(), (), (), ()]) ... Unsafe.head ... (: []) ... Unsafe.head
... (: [()]) ... Unsafe.head ... (: [(), ()]) ... Unsafe.head :: [()] -> [()])

Expand Down
12 changes: 6 additions & 6 deletions src/Universum/VarArg.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module Universum.VarArg
-- >>> import Data.List (zip5)

-- | This type class allows to implement variadic composition operator.
class SuperComposition a b c | a b -> c where
class SuperComposition x y b r | x y b -> r where
-- | Allows to apply function to result of another function with multiple
-- arguments.
--
Expand All @@ -45,16 +45,16 @@ class SuperComposition a b c | a b -> c where
-- disappear due to very general inferred type. However, functions without type
-- specification but with applied @INLINE@ pragma are fast again.
--
(...) :: a -> b -> c
(...) :: (x -> y) -> b -> r

infixl 8 ...

instance {-# INCOHERENT #-} (a ~ c, r ~ b) =>
SuperComposition (a -> b) c r where
instance {-# OVERLAPPABLE #-} (x ~ b, y ~ r) =>
SuperComposition x y b r where
f ... g = f g
{-# INLINE (...) #-}

instance {-# INCOHERENT #-} (SuperComposition (a -> b) d r1, r ~ (c -> r1)) =>
SuperComposition (a -> b) (c -> d) r where
instance {-# OVERLAPPING #-} (SuperComposition x y d r1, r ~ (c -> r1)) =>
SuperComposition x y (c -> d) r where
(f ... g) c = f ... g c
{-# INLINE (...) #-}

0 comments on commit 4791828

Please sign in to comment.