{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -Wno-orphans #-}

module Test.VMap where

import Control.Exception
import qualified Data.List as List
import qualified Data.Map.Strict as Map
import Data.VMap as VMap
import Test.Cardano.Base.QuickCheck (testLawsGroup)
import Test.Hspec
import Test.Hspec.QuickCheck (prop)
import Test.QuickCheck
import Test.QuickCheck.Classes (
  eqLaws,
  isListLaws,
  monoidLaws,
  semigroupLaws,
 )

type MapT = Map.Map Char Int

type VMapT = VMap VB VP Char Int

instance
  (Ord k, Vector kv k, Vector vv v, Arbitrary k, Arbitrary v) =>
  Arbitrary (VMap kv vv k v)
  where
  arbitrary :: Gen (VMap kv vv k v)
arbitrary =
    Map k v -> VMap kv vv k v
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
Map k v -> VMap kv vv k v
VMap.fromMap (Map k v -> VMap kv vv k v)
-> ([(k, v)] -> Map k v) -> [(k, v)] -> VMap kv vv k v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(k, v)] -> Map k v
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(k, v)] -> VMap kv vv k v)
-> Gen [(k, v)] -> Gen (VMap kv vv k v)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen [(k, v)]
forall a. Arbitrary a => Gen a
arbitrary

prop_Roundtrip :: (VMapT -> a) -> (a -> VMapT) -> VMapT -> Property
prop_Roundtrip :: forall a. (VMapT -> a) -> (a -> VMapT) -> VMapT -> Property
prop_Roundtrip VMapT -> a
to a -> VMapT
from VMapT
km = a -> VMapT
from (VMapT -> a
to VMapT
km) VMapT -> VMapT -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== VMapT
km

prop_AsMapTo ::
  (Show a, Eq a) => (VMapT -> a) -> (MapT -> a) -> VMapT -> Property
prop_AsMapTo :: forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (Map Char Int -> a) -> VMapT -> Property
prop_AsMapTo VMapT -> a
fromVM Map Char Int -> a
fromM VMapT
vm = VMapT -> a
fromVM VMapT
vm a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Map Char Int -> a
fromM (VMapT -> Map Char Int
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> Map k v
toMap VMapT
vm)

prop_AsMapFrom :: (a -> VMapT) -> (a -> MapT) -> a -> Property
prop_AsMapFrom :: forall a. (a -> VMapT) -> (a -> Map Char Int) -> a -> Property
prop_AsMapFrom a -> VMapT
mkVMap a -> Map Char Int
mkMap a
a = VMapT -> Map Char Int
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> Map k v
toMap (a -> VMapT
mkVMap a
a) Map Char Int -> Map Char Int -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a -> Map Char Int
mkMap a
a

data ThunkException = ThunkException
  deriving (ThunkException -> ThunkException -> Bool
(ThunkException -> ThunkException -> Bool)
-> (ThunkException -> ThunkException -> Bool) -> Eq ThunkException
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ThunkException -> ThunkException -> Bool
== :: ThunkException -> ThunkException -> Bool
$c/= :: ThunkException -> ThunkException -> Bool
/= :: ThunkException -> ThunkException -> Bool
Eq, Int -> ThunkException -> ShowS
[ThunkException] -> ShowS
ThunkException -> String
(Int -> ThunkException -> ShowS)
-> (ThunkException -> String)
-> ([ThunkException] -> ShowS)
-> Show ThunkException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ThunkException -> ShowS
showsPrec :: Int -> ThunkException -> ShowS
$cshow :: ThunkException -> String
show :: ThunkException -> String
$cshowList :: [ThunkException] -> ShowS
showList :: [ThunkException] -> ShowS
Show)

instance Exception ThunkException

vMapTests :: Spec
vMapTests :: Spec
vMapTests =
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"VMap" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"roundtrip" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      String -> (VMapT -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"to/fromAscDistinctList" ((VMapT -> Property) -> Spec) -> (VMapT -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$
        (VMapT -> [(Char, Int)])
-> ([(Char, Int)] -> VMapT) -> VMapT -> Property
forall a. (VMapT -> a) -> (a -> VMapT) -> VMapT -> Property
prop_Roundtrip VMapT -> [(Char, Int)]
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> [(k, v)]
VMap.toAscList [(Char, Int)] -> VMapT
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromDistinctAscList
      String -> (VMapT -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"to/fromAscList" ((VMapT -> Property) -> Spec) -> (VMapT -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ (VMapT -> [(Char, Int)])
-> ([(Char, Int)] -> VMapT) -> VMapT -> Property
forall a. (VMapT -> a) -> (a -> VMapT) -> VMapT -> Property
prop_Roundtrip VMapT -> [(Char, Int)]
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> [(k, v)]
VMap.toAscList [(Char, Int)] -> VMapT
forall k (kv :: * -> *) (vv :: * -> *) v.
(Eq k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromAscList
      String -> (VMapT -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"to/fromList" ((VMapT -> Property) -> Spec) -> (VMapT -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ (VMapT -> [(Char, Int)])
-> ([(Char, Int)] -> VMapT) -> VMapT -> Property
forall a. (VMapT -> a) -> (a -> VMapT) -> VMapT -> Property
prop_Roundtrip VMapT -> [(Char, Int)]
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> [(k, v)]
VMap.toAscList [(Char, Int)] -> VMapT
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromList
      String -> (VMapT -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"to/fromMap" ((VMapT -> Property) -> Spec) -> (VMapT -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ (VMapT -> Map Char Int)
-> (Map Char Int -> VMapT) -> VMapT -> Property
forall a. (VMapT -> a) -> (a -> VMapT) -> VMapT -> Property
prop_Roundtrip VMapT -> Map Char Int
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> Map k v
VMap.toMap Map Char Int -> VMapT
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
Map k v -> VMap kv vv k v
VMap.fromMap
    String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"strictness" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      let bottom :: a
          bottom :: forall a. a
bottom = ThunkException -> a
forall a e. (HasCallStack, Exception e) => e -> a
throw ThunkException
ThunkException
      String
-> ([(String, String)] -> [(String, String)] -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"fromList" (([(String, String)] -> [(String, String)] -> IO ()) -> Spec)
-> ([(String, String)] -> [(String, String)] -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$ \[(String, String)]
xs [(String, String)]
ys -> do
        let
          vmapKeyThunk, vmapValueThunk :: VMap VB VB String String
          vmapKeyThunk :: VMap VB VB String String
vmapKeyThunk = [(String, String)] -> VMap VB VB String String
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromList ([(String, String)] -> VMap VB VB String String)
-> [(String, String)] -> VMap VB VB String String
forall a b. (a -> b) -> a -> b
$ [(String, String)]
xs [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String
forall a. a
bottom, String
"value")] [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String, String)]
ys
          vmapValueThunk :: VMap VB VB String String
vmapValueThunk = [(String, String)] -> VMap VB VB String String
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromList ([(String, String)] -> VMap VB VB String String)
-> [(String, String)] -> VMap VB VB String String
forall a b. (a -> b) -> a -> b
$ [(String, String)]
xs [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String
"key", String
forall a. a
bottom)] [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String, String)]
ys
        VMap VB VB String String -> IO (VMap VB VB String String)
forall a. a -> IO a
evaluate VMap VB VB String String
vmapKeyThunk IO (VMap VB VB String String) -> (ThunkException -> Bool) -> IO ()
forall e a.
(HasCallStack, Exception e) =>
IO a -> Selector e -> IO ()
`shouldThrow` (ThunkException -> ThunkException -> Bool
forall a. Eq a => a -> a -> Bool
== ThunkException
ThunkException)
        VMap VB VB String String -> IO (VMap VB VB String String)
forall a. a -> IO a
evaluate VMap VB VB String String
vmapValueThunk IO (VMap VB VB String String) -> (ThunkException -> Bool) -> IO ()
forall e a.
(HasCallStack, Exception e) =>
IO a -> Selector e -> IO ()
`shouldThrow` (ThunkException -> ThunkException -> Bool
forall a. Eq a => a -> a -> Bool
== ThunkException
ThunkException)
      String
-> ([(String, String)] -> [(String, String)] -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"map" (([(String, String)] -> [(String, String)] -> IO ()) -> Spec)
-> ([(String, String)] -> [(String, String)] -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$ \[(String, String)]
xs [(String, String)]
ys -> do
        let
          vmapValueThunk :: VMap VB VB String String
          vmapValueThunk :: VMap VB VB String String
vmapValueThunk =
            ShowS -> VMap VB VB String String -> VMap VB VB String String
forall (kv :: * -> *) k (vv :: * -> *) a b.
(Vector kv k, Vector vv a, Vector vv b) =>
(a -> b) -> VMap kv vv k a -> VMap kv vv k b
VMap.map (\String
v -> if String
v String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"bottom" then String
forall a. a
bottom else String
v) (VMap VB VB String String -> VMap VB VB String String)
-> VMap VB VB String String -> VMap VB VB String String
forall a b. (a -> b) -> a -> b
$
              [(String, String)] -> VMap VB VB String String
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromList ([(String, String)] -> VMap VB VB String String)
-> [(String, String)] -> VMap VB VB String String
forall a b. (a -> b) -> a -> b
$
                [(String, String)]
xs [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String
"key", String
"bottom")] [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String, String)]
ys
        VMap VB VB String String -> IO (VMap VB VB String String)
forall a. a -> IO a
evaluate VMap VB VB String String
vmapValueThunk IO (VMap VB VB String String) -> (ThunkException -> Bool) -> IO ()
forall e a.
(HasCallStack, Exception e) =>
IO a -> Selector e -> IO ()
`shouldThrow` (ThunkException -> ThunkException -> Bool
forall a. Eq a => a -> a -> Bool
== ThunkException
ThunkException)
      String
-> ([(String, String)] -> [(String, String)] -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"mapWithKey" (([(String, String)] -> [(String, String)] -> IO ()) -> Spec)
-> ([(String, String)] -> [(String, String)] -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$ \[(String, String)]
xs [(String, String)]
ys -> do
        let
          vmapKeyThunk, vmapValueThunk :: VMap VB VB String String
          vmapKeyThunk :: VMap VB VB String String
vmapKeyThunk =
            (String -> ShowS)
-> VMap VB VB String String -> VMap VB VB String String
forall (kv :: * -> *) k (vv :: * -> *) a b.
(Vector kv k, Vector vv a, Vector vv b) =>
(k -> a -> b) -> VMap kv vv k a -> VMap kv vv k b
VMap.mapWithKey (\String
k String
v -> if String
k String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"bottom" then String
forall a. a
bottom else String
v) (VMap VB VB String String -> VMap VB VB String String)
-> VMap VB VB String String -> VMap VB VB String String
forall a b. (a -> b) -> a -> b
$
              [(String, String)] -> VMap VB VB String String
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromList ([(String, String)] -> VMap VB VB String String)
-> [(String, String)] -> VMap VB VB String String
forall a b. (a -> b) -> a -> b
$
                [(String, String)]
xs [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String
"bottom", String
"value")] [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String, String)]
ys
          vmapValueThunk :: VMap VB VB String String
vmapValueThunk =
            (String -> ShowS)
-> VMap VB VB String String -> VMap VB VB String String
forall (kv :: * -> *) k (vv :: * -> *) a b.
(Vector kv k, Vector vv a, Vector vv b) =>
(k -> a -> b) -> VMap kv vv k a -> VMap kv vv k b
VMap.mapWithKey (\String
_ String
v -> if String
v String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"bottom" then String
forall a. a
bottom else String
v) (VMap VB VB String String -> VMap VB VB String String)
-> VMap VB VB String String -> VMap VB VB String String
forall a b. (a -> b) -> a -> b
$
              [(String, String)] -> VMap VB VB String String
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromList ([(String, String)] -> VMap VB VB String String)
-> [(String, String)] -> VMap VB VB String String
forall a b. (a -> b) -> a -> b
$
                [(String, String)]
xs [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String
"key", String
"bottom")] [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String, String)]
ys
        VMap VB VB String String -> IO (VMap VB VB String String)
forall a. a -> IO a
evaluate VMap VB VB String String
vmapKeyThunk IO (VMap VB VB String String) -> (ThunkException -> Bool) -> IO ()
forall e a.
(HasCallStack, Exception e) =>
IO a -> Selector e -> IO ()
`shouldThrow` (ThunkException -> ThunkException -> Bool
forall a. Eq a => a -> a -> Bool
== ThunkException
ThunkException)
        VMap VB VB String String -> IO (VMap VB VB String String)
forall a. a -> IO a
evaluate VMap VB VB String String
vmapValueThunk IO (VMap VB VB String String) -> (ThunkException -> Bool) -> IO ()
forall e a.
(HasCallStack, Exception e) =>
IO a -> Selector e -> IO ()
`shouldThrow` (ThunkException -> ThunkException -> Bool
forall a. Eq a => a -> a -> Bool
== ThunkException
ThunkException)
    String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"asMap" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      String
-> ([(Char, Int)] -> Fun (Char, Int) (Maybe Int) -> Property)
-> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"mapMaybeWithKey" (([(Char, Int)] -> Fun (Char, Int) (Maybe Int) -> Property)
 -> Spec)
-> ([(Char, Int)] -> Fun (Char, Int) (Maybe Int) -> Property)
-> Spec
forall a b. (a -> b) -> a -> b
$ \[(Char, Int)]
xs Fun (Char, Int) (Maybe Int)
f ->
        (Map Char Int -> VMapT)
-> (Map Char Int -> Map Char Int) -> Map Char Int -> Property
forall a. (a -> VMapT) -> (a -> Map Char Int) -> a -> Property
prop_AsMapFrom
          (\Map Char Int
m -> (Char -> Int -> Maybe Int) -> VMapT -> VMapT
forall (kv :: * -> *) k (vv :: * -> *) a b.
(Vector kv k, Vector vv a, Vector vv b) =>
(k -> a -> Maybe b) -> VMap kv vv k a -> VMap kv vv k b
VMap.mapMaybeWithKey (Fun (Char, Int) (Maybe Int) -> Char -> Int -> Maybe Int
forall a b c. Fun (a, b) c -> a -> b -> c
applyFun2 Fun (Char, Int) (Maybe Int)
f) (Map Char Int -> VMapT
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
Map k v -> VMap kv vv k v
VMap.fromMap Map Char Int
m))
          ((Char -> Int -> Maybe Int) -> Map Char Int -> Map Char Int
forall k a b. (k -> a -> Maybe b) -> Map k a -> Map k b
Map.mapMaybeWithKey (Fun (Char, Int) (Maybe Int) -> Char -> Int -> Maybe Int
forall a b c. Fun (a, b) c -> a -> b -> c
applyFun2 Fun (Char, Int) (Maybe Int)
f) :: MapT -> MapT)
          ([(Char, Int)] -> Map Char Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Char, Int)]
xs)
      String -> ([(Char, Int)] -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"fromList" (([(Char, Int)] -> Property) -> Spec)
-> ([(Char, Int)] -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ ([(Char, Int)] -> VMapT)
-> ([(Char, Int)] -> Map Char Int) -> [(Char, Int)] -> Property
forall a. (a -> VMapT) -> (a -> Map Char Int) -> a -> Property
prop_AsMapFrom [(Char, Int)] -> VMapT
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromList [(Char, Int)] -> Map Char Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
      String
-> ([(Char, Int)] -> Fun (Char, Int, Int) Int -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"fromAscListWithKey" (([(Char, Int)] -> Fun (Char, Int, Int) Int -> Property) -> Spec)
-> ([(Char, Int)] -> Fun (Char, Int, Int) Int -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ \[(Char, Int)]
xs Fun (Char, Int, Int) Int
f ->
        ([(Char, Int)] -> VMapT)
-> ([(Char, Int)] -> Map Char Int) -> [(Char, Int)] -> Property
forall a. (a -> VMapT) -> (a -> Map Char Int) -> a -> Property
prop_AsMapFrom
          ((Char -> Int -> Int -> Int) -> [(Char, Int)] -> VMapT
forall k (kv :: * -> *) (vv :: * -> *) v.
(Eq k, Vector kv k, Vector vv v) =>
(k -> v -> v -> v) -> [(k, v)] -> VMap kv vv k v
VMap.fromAscListWithKey (Fun (Char, Int, Int) Int -> Char -> Int -> Int -> Int
forall a b c d. Fun (a, b, c) d -> a -> b -> c -> d
applyFun3 Fun (Char, Int, Int) Int
f))
          ((Char -> Int -> Int -> Int) -> [(Char, Int)] -> Map Char Int
forall k a. Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a
Map.fromAscListWithKey (Fun (Char, Int, Int) Int -> Char -> Int -> Int -> Int
forall a b c d. Fun (a, b, c) d -> a -> b -> c -> d
applyFun3 Fun (Char, Int, Int) Int
f))
          (((Char, Int) -> Char) -> [(Char, Int)] -> [(Char, Int)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
List.sortOn (Char, Int) -> Char
forall a b. (a, b) -> a
fst [(Char, Int)]
xs)
      String
-> (Int -> [(Char, Int)] -> Fun (Char, Int, Int) Int -> Property)
-> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"fromAscListWithKeyN" ((Int -> [(Char, Int)] -> Fun (Char, Int, Int) Int -> Property)
 -> Spec)
-> (Int -> [(Char, Int)] -> Fun (Char, Int, Int) Int -> Property)
-> Spec
forall a b. (a -> b) -> a -> b
$ \Int
n [(Char, Int)]
xs Fun (Char, Int, Int) Int
f ->
        ([(Char, Int)] -> VMapT)
-> ([(Char, Int)] -> Map Char Int) -> [(Char, Int)] -> Property
forall a. (a -> VMapT) -> (a -> Map Char Int) -> a -> Property
prop_AsMapFrom
          (Int -> (Char -> Int -> Int -> Int) -> [(Char, Int)] -> VMapT
forall k (kv :: * -> *) (vv :: * -> *) v.
(Eq k, Vector kv k, Vector vv v) =>
Int -> (k -> v -> v -> v) -> [(k, v)] -> VMap kv vv k v
VMap.fromAscListWithKeyN Int
n (Fun (Char, Int, Int) Int -> Char -> Int -> Int -> Int
forall a b c d. Fun (a, b, c) d -> a -> b -> c -> d
applyFun3 Fun (Char, Int, Int) Int
f))
          ((Char -> Int -> Int -> Int) -> [(Char, Int)] -> Map Char Int
forall k a. Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a
Map.fromAscListWithKey (Fun (Char, Int, Int) Int -> Char -> Int -> Int -> Int
forall a b c d. Fun (a, b, c) d -> a -> b -> c -> d
applyFun3 Fun (Char, Int, Int) Int
f) ([(Char, Int)] -> Map Char Int)
-> ([(Char, Int)] -> [(Char, Int)])
-> [(Char, Int)]
-> Map Char Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [(Char, Int)] -> [(Char, Int)]
forall a. Int -> [a] -> [a]
take Int
n)
          (((Char, Int) -> Char) -> [(Char, Int)] -> [(Char, Int)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
List.sortOn (Char, Int) -> Char
forall a b. (a, b) -> a
fst [(Char, Int)]
xs)
      String
-> ([(Char, Int)]
    -> [(Char, Int)] -> Fun (Char, Int, Int) Int -> Property)
-> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"unionWithKey" (([(Char, Int)]
  -> [(Char, Int)] -> Fun (Char, Int, Int) Int -> Property)
 -> Spec)
-> ([(Char, Int)]
    -> [(Char, Int)] -> Fun (Char, Int, Int) Int -> Property)
-> Spec
forall a b. (a -> b) -> a -> b
$ \[(Char, Int)]
xs1 [(Char, Int)]
xs2 Fun (Char, Int, Int) Int
f ->
        ((Map Char Int, Map Char Int) -> VMapT)
-> ((Map Char Int, Map Char Int) -> Map Char Int)
-> (Map Char Int, Map Char Int)
-> Property
forall a. (a -> VMapT) -> (a -> Map Char Int) -> a -> Property
prop_AsMapFrom
          (\(Map Char Int
m1, Map Char Int
m2) -> (Char -> Int -> Int -> Int) -> VMapT -> VMapT -> VMapT
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
(k -> v -> v -> v)
-> VMap kv vv k v -> VMap kv vv k v -> VMap kv vv k v
VMap.unionWithKey (Fun (Char, Int, Int) Int -> Char -> Int -> Int -> Int
forall a b c d. Fun (a, b, c) d -> a -> b -> c -> d
applyFun3 Fun (Char, Int, Int) Int
f) (Map Char Int -> VMapT
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
Map k v -> VMap kv vv k v
VMap.fromMap Map Char Int
m1) (Map Char Int -> VMapT
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
Map k v -> VMap kv vv k v
VMap.fromMap Map Char Int
m2))
          ((Map Char Int -> Map Char Int -> Map Char Int)
-> (Map Char Int, Map Char Int) -> Map Char Int
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((Char -> Int -> Int -> Int)
-> Map Char Int -> Map Char Int -> Map Char Int
forall k a.
Ord k =>
(k -> a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWithKey (Fun (Char, Int, Int) Int -> Char -> Int -> Int -> Int
forall a b c d. Fun (a, b, c) d -> a -> b -> c -> d
applyFun3 Fun (Char, Int, Int) Int
f)))
          ([(Char, Int)] -> Map Char Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Char, Int)]
xs1, [(Char, Int)] -> Map Char Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Char, Int)]
xs2)
      String -> ([(Char, Int)] -> [(Char, Int)] -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"mappend" (([(Char, Int)] -> [(Char, Int)] -> Property) -> Spec)
-> ([(Char, Int)] -> [(Char, Int)] -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ \[(Char, Int)]
xs1 [(Char, Int)]
xs2 ->
        ((Map Char Int, Map Char Int) -> VMapT)
-> ((Map Char Int, Map Char Int) -> Map Char Int)
-> (Map Char Int, Map Char Int)
-> Property
forall a. (a -> VMapT) -> (a -> Map Char Int) -> a -> Property
prop_AsMapFrom
          (\(Map Char Int
m1, Map Char Int
m2) -> Map Char Int -> VMapT
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
Map k v -> VMap kv vv k v
VMap.fromMap Map Char Int
m1 VMapT -> VMapT -> VMapT
forall a. Semigroup a => a -> a -> a
<> Map Char Int -> VMapT
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
Map k v -> VMap kv vv k v
VMap.fromMap Map Char Int
m2)
          ((Map Char Int -> Map Char Int -> Map Char Int)
-> (Map Char Int, Map Char Int) -> Map Char Int
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Map Char Int -> Map Char Int -> Map Char Int
forall a. Semigroup a => a -> a -> a
(<>))
          ([(Char, Int)] -> Map Char Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Char, Int)]
xs1, [(Char, Int)] -> Map Char Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Char, Int)]
xs2)
      String -> (VMapT -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"keys" ((VMapT -> Property) -> Spec) -> (VMapT -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ (VMapT -> String) -> (Map Char Int -> String) -> VMapT -> Property
forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (Map Char Int -> a) -> VMapT -> Property
prop_AsMapTo VMapT -> String
forall (kv :: * -> *) k (vv :: * -> *) v.
Vector kv k =>
VMap kv vv k v -> [k]
VMap.keys Map Char Int -> String
forall k a. Map k a -> [k]
Map.keys
      String -> (VMapT -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"keysSet" ((VMapT -> Property) -> Spec) -> (VMapT -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ (VMapT -> Set Char)
-> (Map Char Int -> Set Char) -> VMapT -> Property
forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (Map Char Int -> a) -> VMapT -> Property
prop_AsMapTo VMapT -> Set Char
forall (kv :: * -> *) k (vv :: * -> *) v.
Vector kv k =>
VMap kv vv k v -> Set k
VMap.keysSet Map Char Int -> Set Char
forall k a. Map k a -> Set k
Map.keysSet
      String -> (VMapT -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"elems" ((VMapT -> Property) -> Spec) -> (VMapT -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ (VMapT -> [Int]) -> (Map Char Int -> [Int]) -> VMapT -> Property
forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (Map Char Int -> a) -> VMapT -> Property
prop_AsMapTo VMapT -> [Int]
forall (vv :: * -> *) v (kv :: * -> *) k.
Vector vv v =>
VMap kv vv k v -> [v]
VMap.elems Map Char Int -> [Int]
forall k a. Map k a -> [a]
Map.elems
      String -> (VMapT -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"toAscList" ((VMapT -> Property) -> Spec) -> (VMapT -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ (VMapT -> [(Char, Int)])
-> (Map Char Int -> [(Char, Int)]) -> VMapT -> Property
forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (Map Char Int -> a) -> VMapT -> Property
prop_AsMapTo VMapT -> [(Char, Int)]
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> [(k, v)]
VMap.toAscList Map Char Int -> [(Char, Int)]
forall k a. Map k a -> [(k, a)]
Map.toAscList
      String -> (Fun (Char, Int) String -> VMapT -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"foldMapWithKey" ((Fun (Char, Int) String -> VMapT -> Property) -> Spec)
-> (Fun (Char, Int) String -> VMapT -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ \Fun (Char, Int) String
f ->
        let f' :: Char -> Int -> String
f' Char
k Int
v = Fun (Char, Int) String -> Char -> Int -> String
forall a b c. Fun (a, b) c -> a -> b -> c
applyFun2 Fun (Char, Int) String
f Char
k Int
v :: String
         in (VMapT -> String) -> (Map Char Int -> String) -> VMapT -> Property
forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (Map Char Int -> a) -> VMapT -> Property
prop_AsMapTo ((Char -> Int -> String) -> VMapT -> String
forall (kv :: * -> *) k (vv :: * -> *) v m.
(Vector kv k, Vector vv v, Monoid m) =>
(k -> v -> m) -> VMap kv vv k v -> m
VMap.foldMapWithKey Char -> Int -> String
f') ((Char -> Int -> String) -> Map Char Int -> String
forall m k a. Monoid m => (k -> a -> m) -> Map k a -> m
Map.foldMapWithKey Char -> Int -> String
f')
      String -> (Char -> VMapT -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"lookup" ((Char -> VMapT -> Property) -> Spec)
-> (Char -> VMapT -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ \Char
k -> (VMapT -> Maybe Int)
-> (Map Char Int -> Maybe Int) -> VMapT -> Property
forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (Map Char Int -> a) -> VMapT -> Property
prop_AsMapTo (Char -> VMapT -> Maybe Int
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
k -> VMap kv vv k v -> Maybe v
VMap.lookup Char
k) (Char -> Map Char Int -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Char
k)
      String -> (Char -> VMapT -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"elemAt/lookupIndex" ((Char -> VMapT -> Property) -> Spec)
-> (Char -> VMapT -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ \Char
k VMapT
m ->
        case Char -> VMapT -> Maybe Int
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k) =>
k -> VMap kv vv k v -> Maybe Int
VMap.lookupIndex Char
k VMapT
m of
          Maybe Int
Nothing -> String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
label String
"Nothing" (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Char -> Map Char Int -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe Int
Map.lookupIndex Char
k (VMapT -> Map Char Int
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> Map k v
VMap.toMap VMapT
m) Maybe Int -> Maybe Int -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Maybe Int
forall a. Maybe a
Nothing
          Just Int
ix -> String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
label String
"Just" (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ (VMapT -> (Char, Int))
-> (Map Char Int -> (Char, Int)) -> VMapT -> Property
forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (Map Char Int -> a) -> VMapT -> Property
prop_AsMapTo (Int -> VMapT -> (Char, Int)
forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
Int -> VMap kv vv k v -> (k, v)
VMap.elemAt Int
ix) (Int -> Map Char Int -> (Char, Int)
forall k a. Int -> Map k a -> (k, a)
Map.elemAt Int
ix) VMapT
m
      String -> (Char -> Int -> [(Char, Int)] -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"lookup (existing)" ((Char -> Int -> [(Char, Int)] -> Property) -> Spec)
-> (Char -> Int -> [(Char, Int)] -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ \Char
k Int
v [(Char, Int)]
xs ->
        let xs' :: [(Char, Int)]
xs' = [(Char, Int)]
xs [(Char, Int)] -> [(Char, Int)] -> [(Char, Int)]
forall a. Semigroup a => a -> a -> a
<> [(Char
k, Int
v)]
         in (Char -> VMapT -> Maybe Int
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
k -> VMap kv vv k v -> Maybe v
VMap.lookup Char
k ([(Char, Int)] -> VMapT
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromList [(Char, Int)]
xs' :: VMapT) Maybe Int -> Maybe Int -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Int -> Maybe Int
forall a. a -> Maybe a
Just Int
v)
              Property -> Property -> Property
forall prop1 prop2.
(Testable prop1, Testable prop2) =>
prop1 -> prop2 -> Property
.&&. (Char -> Map Char Int -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Char
k ([(Char, Int)] -> Map Char Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Char, Int)]
xs' :: MapT) Maybe Int -> Maybe Int -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Int -> Maybe Int
forall a. a -> Maybe a
Just Int
v)
      String -> (Int -> Char -> VMapT -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"findWithDefault" ((Int -> Char -> VMapT -> Property) -> Spec)
-> (Int -> Char -> VMapT -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ \Int
d Char
k ->
        (VMapT -> Int) -> (Map Char Int -> Int) -> VMapT -> Property
forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (Map Char Int -> a) -> VMapT -> Property
prop_AsMapTo (Int -> Char -> VMapT -> Int
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
v -> k -> VMap kv vv k v -> v
VMap.findWithDefault Int
d Char
k) (Int -> Char -> Map Char Int -> Int
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault Int
d Char
k)
      String -> (Char -> Int -> [(Char, Int)] -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"findWithDefault (existing)" ((Char -> Int -> [(Char, Int)] -> Property) -> Spec)
-> (Char -> Int -> [(Char, Int)] -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ \Char
k Int
v [(Char, Int)]
xs ->
        let xs' :: [(Char, Int)]
xs' = [(Char, Int)]
xs [(Char, Int)] -> [(Char, Int)] -> [(Char, Int)]
forall a. Semigroup a => a -> a -> a
<> [(Char
k, Int
v)]
            unfound :: a
unfound = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
"the expected key " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Char -> String
forall a. Show a => a -> String
show Char
k String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" was not found"
         in (Int -> Char -> VMapT -> Int
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
v -> k -> VMap kv vv k v -> v
VMap.findWithDefault Int
forall a. a
unfound Char
k ([(Char, Int)] -> VMapT
forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromList [(Char, Int)]
xs' :: VMapT) Int -> Int -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Int
v)
              Property -> Property -> Property
forall prop1 prop2.
(Testable prop1, Testable prop2) =>
prop1 -> prop2 -> Property
.&&. (Int -> Char -> Map Char Int -> Int
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault Int
forall a. a
unfound Char
k ([(Char, Int)] -> Map Char Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Char, Int)]
xs' :: MapT) Int -> Int -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Int
v)
    forall a. [Proxy a -> Laws] -> Spec
testLawsGroup @VMapT
      [ Proxy VMapT -> Laws
forall a. (Eq a, Arbitrary a, Show a) => Proxy a -> Laws
eqLaws
      , Proxy VMapT -> Laws
forall a.
(Semigroup a, Eq a, Arbitrary a, Show a) =>
Proxy a -> Laws
semigroupLaws
      , Proxy VMapT -> Laws
forall a. (Monoid a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
monoidLaws
      , Proxy VMapT -> Laws
forall a.
(IsList a, Show a, Show (Item a), Arbitrary a, Arbitrary (Item a),
 Eq a) =>
Proxy a -> Laws
isListLaws
      ]