multicurryable 0.1.0.0 → 0.1.0.1
raw patch · 6 files changed
+113/−66 lines, 6 filesdep +doctestPVP ok
version bump matches the API change (PVP)
Dependencies added: doctest
API changes (from Hackage documentation)
Files
- CHANGELOG.md +4/−0
- lib/Multicurryable.hs +34/−2
- multicurryable.cabal +12/−13
- test/Main.hs +0/−51
- test/doctests.hs +9/−0
- test/tests.hs +54/−0
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for bunchable +## 0.1.0.1++* Doctests+ ## 0.1.0.0 -- YYYY-mm-dd * First version. Released on an unsuspecting world.
lib/Multicurryable.hs view
@@ -9,10 +9,42 @@ -- | While writing function decorators, we often need to store the arguments -- of the function in a n-ary product. @'multiuncurry' \@(<-)@ is useful for that. --+-- >>> :{+-- type Fun0 = Int+-- type UFun0 = NP I '[] -> Int+-- type Fun1 = Bool -> Int+-- type UFun1 = NP I '[Bool] -> Int+-- type Fun2 = Char -> Bool -> Int+-- type UFun2 = NP I '[Char, Bool] -> Int+-- ufun0 :: UFun0 = multiuncurry @(->) @_ @_ @Fun0 $ 5+-- ufun1 :: UFun1 = multiuncurry @(->) @_ @_ @Fun1 $ \_ -> 5+-- ufun2 :: UFun2 = multiuncurry @(->) @_ @_ @Fun2 $ \_ _ -> 5+-- fun0 :: Fun0 = multicurry @(->) @_ @_ ufun0 +-- fun1 :: Fun1 = multicurry @(->) @_ @_ ufun1 +-- fun2 :: Fun2 = multicurry @(->) @_ @_ ufun2+-- :}+--+-- -- Less often, when processing the result of functions, we have a nested chain -- of 'Either's like @Either Err1 (Either Err2 (Either Err3 Success))@, and want to put all the errors in a top-level 'Left' branch, -- and the lone @Success@ value in a top-level 'Right' branch. @'multiuncurry' \@Either@ is useful for that. -- +-- >>> :{+-- type Eith0 = Int+-- type Eith1 = Either Bool Int+-- type Eith2 = Either Char (Either Bool Int)+-- type UEith0 = Either (NS I '[]) Int+-- type UEith1 = Either (NS I '[Bool]) Int+-- type UEith2 = Either (NS I '[Char, Bool]) Int+-- ueith0 :: UEith0 = multiuncurry @Either @_ @_ @Eith0 5+-- ueith1 :: UEith1 = multiuncurry @Either @_ @_ @Eith1 $ Right 5+-- ueith2 :: UEith2 = multiuncurry @Either @_ @_ @Eith2 $ Right (Right 5)+-- eith0 :: Eith0 = multicurry @Either @_ @_ ueith0+-- eith1 :: Eith1 = multicurry @Either @_ @_ ueith1+-- eith2 :: Eith2 = multicurry @Either @_ @_ ueith2+-- :}+--+-- -- The 'Multicurryable' class will get terribly confused if it can't determine -- the rightmost type, because it can't be sure it's not another @(->)@, or -- another @Either@. So use it only with concrete rightmost types, not@@ -29,8 +61,6 @@ import Data.Kind import Data.SOP-import Data.SOP.NP-import Data.SOP.NS type Multicurryable :: (Type -> Type -> Type) -> [Type] -> Type -> Type -> Constraint class@@ -136,3 +166,5 @@ -- >>> :set -XTypeFamilies -- >>> :set -XTypeOperators -- >>> :set -XUndecidableInstances +-- >>> import Multicurryable+-- >>> import Data.SOP
multicurryable.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: multicurryable-version: 0.1.0.0+version: 0.1.0.1 synopsis: Uncurry functions with multiple arguments. description: This library provides a version of "uncurry" which takes a function of multiple arguments and stores the arguments into an n-ary product@@ -40,20 +40,19 @@ -- other-extensions: type: exitcode-stdio-1.0 hs-source-dirs: test- main-is: Main.hs+ main-is: tests.hs build-depends: base >= 4.16 && < 5, sop-core ^>= 0.5.0.2, multicurryable --- test-suite doctests--- import: warnings--- type: exitcode-stdio-1.0--- hs-source-dirs: doctest--- main-is: Main.hs--- build-depends: --- base >= 4.16 && < 5,--- sop-core ^>= 0.5.0.2,--- doctest,--- multicurryable,--- default-language: GHC2021+test-suite doctests+ import: warnings+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: doctests.hs+ build-depends: + base >= 4.16 && < 5,+ doctest ^>= 0.20.1,+ multicurryable,+ default-language: GHC2021
− test/Main.hs
@@ -1,51 +0,0 @@-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE BlockArguments #-}-module Main (main) where--import Multicurryable-import Data.SOP.NP-import Data.SOP.NS-import Data.Functor.Identity--type Fun0 = Int-type Fun0b = IO Int-type Fun1 = Bool -> Int-type Fun1b = Bool -> IO Int-type Fun2 = Char -> Bool -> Int-type Fun2b = Char -> Bool -> IO Int---- Signatures omitted to check type inference-ufun0 = multiuncurry @(->) @_ @_ @Fun0 5-ufun0b = multiuncurry @(->) @_ @_ @Fun0b (pure 5)-ufun1 = multiuncurry @(->) @_ @_ @Fun1 \_ -> 5-ufun1b = multiuncurry @(->) @_ @_ @Fun1b \_ -> pure 5-ufun2 = multiuncurry @(->) @_ @_ @Fun2 \_ _ -> 5-ufun2b = multiuncurry @(->) @_ @_ @Fun2b \_ _ -> pure 5--fun0 = multicurry @(->) @_ @_ ufun0 -fun0b = multicurry @(->) @_ @_ ufun0b-fun1 = multicurry @(->) @_ @_ ufun1 -fun1b = multicurry @(->) @_ @_ ufun1b-fun2 = multicurry @(->) @_ @_ ufun2-fun2b = multicurry @(->) @_ @_ ufun2b---type Eith0 = Int-type Eith1 = Either Bool Int-type Eith2 = Either Char (Either Bool Int)--ueith0 = multiuncurry @Either @_ @_ @Eith0 5-ueith1 = multiuncurry @Either @_ @_ @Eith1 $ Right 5-ueith2 = multiuncurry @Either @_ @_ @Eith2 $ Right (Right 5)--eith0 = multicurry @Either @_ @_ ueith0-eith1 = multicurry @Either @_ @_ ueith1-eith2 = multicurry @Either @_ @_ ueith2--main :: IO ()-main = putStrLn "Test suite not yet implemented."
+ test/doctests.hs view
@@ -0,0 +1,9 @@+module Main (main) where++import Test.DocTest++main :: IO ()+main = doctest [+ "-ilib", + "lib/Multicurryable.hs" + ]
+ test/tests.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE BlockArguments #-}+module Main (main) where++import Multicurryable+import Data.SOP.NP+import Data.SOP.NS+import Data.Functor.Identity++type Fun0 = Int+type Fun0b = IO Int+type Fun1 = Bool -> Int+type Fun1b = Bool -> IO Int+type Fun2 = Char -> Bool -> Int+type Fun2b = Char -> Bool -> IO Int++-- Signatures omitted to check type inference+ufun0 = multiuncurry @(->) @_ @_ @Fun0 5+ufun0b = multiuncurry @(->) @_ @_ @Fun0b (pure 5)+ufun1 = multiuncurry @(->) @_ @_ @Fun1 \_ -> 5+ufun1b = multiuncurry @(->) @_ @_ @Fun1b \_ -> pure 5+ufun2 = multiuncurry @(->) @_ @_ @Fun2 \_ _ -> 5+ufun2b = multiuncurry @(->) @_ @_ @Fun2b \_ _ -> pure 5++fun0 = multicurry @(->) @_ @_ ufun0 +fun0b = multicurry @(->) @_ @_ ufun0b+fun1 = multicurry @(->) @_ @_ ufun1 +fun1b = multicurry @(->) @_ @_ ufun1b+fun2 = multicurry @(->) @_ @_ ufun2+fun2b = multicurry @(->) @_ @_ ufun2b+++type Eith0 = Int+type Eith1 = Either Bool Int+type Eith2 = Either Char (Either Bool Int)++ueith0 :: Either (NS I '[]) Int+ueith0 = multiuncurry @Either @_ @_ @Eith0 5+ueith1 :: Either (NS I '[Bool]) Int+ueith1 = multiuncurry @Either @_ @_ @Eith1 $ Right 5+ueith2 :: Either (NS I '[Char, Bool]) Int+ueith2 = multiuncurry @Either @_ @_ @Eith2 $ Right (Right 5)++eith0 = multicurry @Either @_ @_ ueith0+eith1 = multicurry @Either @_ @_ ueith1+eith2 = multicurry @Either @_ @_ ueith2++main :: IO ()+main = putStrLn "Test suite not yet implemented."