packages feed

foundation 0.0.4 → 0.0.5

raw patch · 45 files changed

+1799/−143 lines, 45 filesdep ~basedep ~doctestPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base, doctest

API changes (from Hackage documentation)

- Foundation.System.Info: instance GHC.Classes.Eq Foundation.System.Info.Endianness
- Foundation.System.Info: instance GHC.Show.Show Foundation.System.Info.Endianness
+ Foundation.Check: (===) :: Eq a => a -> a -> Property
+ Foundation.Check: Prop :: Gen Bool -> Property
+ Foundation.Check: [Group] :: String -> [Test] -> Test
+ Foundation.Check: [Property] :: IsProperty prop => String -> prop -> Test
+ Foundation.Check: [Unit] :: String -> IO () -> Test
+ Foundation.Check: [unProp] :: Property -> Gen Bool
+ Foundation.Check: arbitrary :: Arbitrary a => Gen a
+ Foundation.Check: class Arbitrary a
+ Foundation.Check: class IsProperty p
+ Foundation.Check: data Gen a
+ Foundation.Check: data Property
+ Foundation.Check: data Test
+ Foundation.Check: defaultMain :: Test -> IO ()
+ Foundation.Check: infix 4 ===
+ Foundation.Check: instance GHC.Classes.Eq Foundation.Check.PropertyResult
+ Foundation.Check: instance GHC.Show.Show Foundation.Check.PropertyResult
+ Foundation.Check: instance GHC.Show.Show Foundation.Check.TestResult
+ Foundation.Check: property :: IsProperty p => p -> Property
+ Foundation.Check: testName :: Test -> String
+ Foundation.Class.Storable: peekArray :: (Buildable col, StorableFixed (Element col)) => Size (Element col) -> Ptr (Element col) -> IO col
+ Foundation.Class.Storable: peekArrayEndedBy :: (Buildable col, StorableFixed (Element col), Eq (Element col), Show (Element col)) => Element col -> Ptr (Element col) -> IO col
+ Foundation.Class.Storable: pokeArray :: (Sequential col, StorableFixed (Element col)) => Ptr (Element col) -> col -> IO ()
+ Foundation.Class.Storable: pokeArrayEndedBy :: (Sequential col, StorableFixed (Element col)) => Element col -> Ptr (Element col) -> col -> IO ()
+ Foundation.Collection: class Functor collection => Mappable collection where traverse f = sequenceA . fmap f sequenceA = traverse id mapM = traverse sequence = sequenceA
+ Foundation.Collection: forM :: (Mappable col, Applicative m, Monad m) => col a -> (a -> m b) -> m (col b)
+ Foundation.Collection: forM_ :: (Mappable col, Applicative m, Monad m) => col a -> (a -> m b) -> m ()
+ Foundation.Collection: mapM :: (Mappable collection, Applicative m, Monad m) => (a -> m b) -> collection a -> m (collection b)
+ Foundation.Collection: mapM_ :: (Mappable col, Applicative m, Monad m) => (a -> m b) -> col a -> m ()
+ Foundation.Collection: sequence :: (Mappable collection, Applicative m, Monad m) => collection (m a) -> m (collection a)
+ Foundation.Collection: sequenceA :: (Mappable collection, Applicative f) => collection (f a) -> f (collection a)
+ Foundation.Collection: traverse :: (Mappable collection, Applicative f) => (a -> f b) -> collection a -> f (collection b)
+ Foundation.Collection: traverse_ :: (Mappable col, Applicative f) => (a -> f b) -> col a -> f ()
+ Foundation.List.SList: append :: SList n a -> SList m a -> SList (n + m) a
+ Foundation.List.SList: cons :: a -> SList n a -> SList (n + 1) a
+ Foundation.List.SList: create :: forall a (n :: Nat). KnownNat n => (Integer -> a) -> SList n a
+ Foundation.List.SList: createFrom :: forall a (n :: Nat) (start :: Nat). (KnownNat n, KnownNat start) => Proxy start -> (Integer -> a) -> SList n a
+ Foundation.List.SList: data SList (n :: Nat) a
+ Foundation.List.SList: drop :: forall a d (m :: Nat) (n :: Nat). (KnownNat d, NatWithinBound Int d, (n - m) ~ d, m <= n) => SList n a -> SList m a
+ Foundation.List.SList: elem :: Eq a => a -> SList n a -> Bool
+ Foundation.List.SList: empty :: SList 0 a
+ Foundation.List.SList: foldl :: (b -> a -> b) -> b -> SList n a -> b
+ Foundation.List.SList: head :: CmpNat n 0 ~ GT => SList n a -> a
+ Foundation.List.SList: length :: forall a (n :: Nat). (KnownNat n, NatWithinBound Int n) => SList n a -> Int
+ Foundation.List.SList: map :: (a -> b) -> SList n a -> SList n b
+ Foundation.List.SList: maximum :: (Ord a, CmpNat n 0 ~ GT) => SList n a -> a
+ Foundation.List.SList: minimum :: (Ord a, CmpNat n 0 ~ GT) => SList n a -> a
+ Foundation.List.SList: replicateM :: forall (n :: Nat) m a. (n <= 1048576, Monad m, KnownNat n) => m a -> m (SList n a)
+ Foundation.List.SList: singleton :: a -> SList 1 a
+ Foundation.List.SList: tail :: CmpNat n 0 ~ GT => SList n a -> SList (n - 1) a
+ Foundation.List.SList: take :: forall a (m :: Nat) (n :: Nat). (KnownNat m, NatWithinBound Int m, m <= n) => SList n a -> SList m a
+ Foundation.List.SList: toSList :: forall (n :: Nat) a. (KnownNat n, NatWithinBound Int n) => [a] -> Maybe (SList n a)
+ Foundation.List.SList: unSList :: SList n a -> [a]
+ Foundation.List.SList: uncons :: CmpNat n 0 ~ GT => SList n a -> (a, SList (n - 1) a)
+ Foundation.List.SList: zip :: SList n a -> SList n b -> SList n (a, b)
+ Foundation.List.SList: zip3 :: SList n a -> SList n b -> SList n c -> SList n (a, b, c)
+ Foundation.List.SList: zip4 :: SList n a -> SList n b -> SList n c -> SList n d -> SList n (a, b, c, d)
+ Foundation.List.SList: zip5 :: SList n a -> SList n b -> SList n c -> SList n d -> SList n e -> SList n (a, b, c, d, e)
+ Foundation.List.SList: zipWith :: (a -> b -> x) -> SList n a -> SList n b -> SList n x
+ Foundation.List.SList: zipWith3 :: (a -> b -> c -> x) -> SList n a -> SList n b -> SList n c -> SList n x
+ Foundation.List.SList: zipWith4 :: (a -> b -> c -> d -> x) -> SList n a -> SList n b -> SList n c -> SList n d -> SList n x
+ Foundation.List.SList: zipWith5 :: (a -> b -> c -> d -> e -> x) -> SList n a -> SList n b -> SList n c -> SList n d -> SList n e -> SList n x
+ Foundation.Network.HostName: HostName :: String -> HostName
+ Foundation.Network.HostName: HostNameInfo :: !HostName -> !(Array HostName) -> !(Array address_type) -> HostNameInfo address_type
+ Foundation.Network.HostName: [addresses] :: HostNameInfo address_type -> !(Array address_type)
+ Foundation.Network.HostName: [aliases] :: HostNameInfo address_type -> !(Array HostName)
+ Foundation.Network.HostName: [officialName] :: HostNameInfo address_type -> !HostName
+ Foundation.Network.HostName: [toString] :: HostName -> String
+ Foundation.Network.HostName: data HostNameInfo address_type
+ Foundation.Network.HostName: getHostNameInfo :: (Eq address_type, Storable address_type, SocketFamily address_type) => HostName -> IO (HostNameInfo address_type)
+ Foundation.Network.HostName: getHostNameInfo_ :: (SocketFamily address_type, Eq address_type, Storable address_type) => Proxy address_type -> HostName -> IO (HostNameInfo address_type)
+ Foundation.Network.HostName: instance Data.String.IsString Foundation.Network.HostName.HostName
+ Foundation.Network.HostName: instance Foundation.Hashing.Hashable.Hashable Foundation.Network.HostName.HostName
+ Foundation.Network.HostName: instance Foundation.Network.HostName.SocketFamily Foundation.Network.IPv4.IPv4
+ Foundation.Network.HostName: instance Foundation.Network.HostName.SocketFamily Foundation.Network.IPv6.IPv6
+ Foundation.Network.HostName: instance GHC.Classes.Eq Foundation.Network.HostName.HostName
+ Foundation.Network.HostName: instance GHC.Classes.Eq Foundation.Network.HostName.HostNameError
+ Foundation.Network.HostName: instance GHC.Classes.Eq address_type => GHC.Classes.Eq (Foundation.Network.HostName.HostNameInfo address_type)
+ Foundation.Network.HostName: instance GHC.Classes.Ord Foundation.Network.HostName.HostName
+ Foundation.Network.HostName: instance GHC.Classes.Ord address_type => GHC.Classes.Ord (Foundation.Network.HostName.HostNameInfo address_type)
+ Foundation.Network.HostName: instance GHC.Exception.Exception Foundation.Network.HostName.HostNameError
+ Foundation.Network.HostName: instance GHC.Show.Show Foundation.Network.HostName.HostName
+ Foundation.Network.HostName: instance GHC.Show.Show Foundation.Network.HostName.HostNameError
+ Foundation.Network.HostName: instance GHC.Show.Show address_type => GHC.Show.Show (Foundation.Network.HostName.HostNameInfo address_type)
+ Foundation.Network.HostName: newtype HostName
+ Foundation.Network.IPv4: any :: IPv4
+ Foundation.Network.IPv4: loopback :: IPv4
+ Foundation.Network.IPv6: any :: IPv6
+ Foundation.Network.IPv6: loopback :: IPv6
+ Foundation.Primitive: class IntegralCast a b where integralCast = id
+ Foundation.Primitive: class IntegralDownsize a b where integralDownsize = id
+ Foundation.Primitive: class IntegralUpsize a b
+ Foundation.Primitive: integralCast :: (IntegralCast a b, a ~ b) => a -> b
+ Foundation.Primitive: integralDownsize :: (IntegralDownsize a b, a ~ b) => a -> b
+ Foundation.Primitive: integralDownsizeCheck :: IntegralDownsize a b => a -> Maybe b
+ Foundation.Primitive: integralUpsize :: IntegralUpsize a b => a -> b
+ Foundation.Primitive.Nat: class KnownNat (n :: Nat)
+ Foundation.Primitive.Nat: data Nat :: *
+ Foundation.Primitive.Nat: natVal :: KnownNat n => proxy n -> Integer
+ Foundation.Primitive.Nat: natValInt :: forall n proxy. (KnownNat n, NatWithinBound Int n) => proxy n -> Int
+ Foundation.Primitive.Nat: natValInt16 :: forall n proxy. (KnownNat n, NatWithinBound Int16 n) => proxy n -> Int16
+ Foundation.Primitive.Nat: natValInt32 :: forall n proxy. (KnownNat n, NatWithinBound Int32 n) => proxy n -> Int32
+ Foundation.Primitive.Nat: natValInt64 :: forall n proxy. (KnownNat n, NatWithinBound Int64 n) => proxy n -> Int64
+ Foundation.Primitive.Nat: natValInt8 :: forall n proxy. (KnownNat n, NatWithinBound Int8 n) => proxy n -> Int8
+ Foundation.Primitive.Nat: natValWord :: forall n proxy. (KnownNat n, NatWithinBound Word n) => proxy n -> Word
+ Foundation.Primitive.Nat: natValWord16 :: forall n proxy. (KnownNat n, NatWithinBound Word16 n) => proxy n -> Word16
+ Foundation.Primitive.Nat: natValWord32 :: forall n proxy. (KnownNat n, NatWithinBound Word32 n) => proxy n -> Word32
+ Foundation.Primitive.Nat: natValWord64 :: forall n proxy. (KnownNat n, NatWithinBound Word64 n) => proxy n -> Word64
+ Foundation.Primitive.Nat: natValWord8 :: forall n proxy. (KnownNat n, NatWithinBound Word8 n) => proxy n -> Word8
+ Foundation.Primitive.Nat: type (<=) (x :: Nat) (y :: Nat) = (~) Bool ((<=?) x y) True
+ Foundation.Random: getRandomPrimType :: forall randomly ty. (PrimType ty, MonadRandom randomly) => randomly ty
+ Foundation.Random: randomNewFrom :: RandomGen gen => UArray Word8 -> Maybe gen
+ Foundation.UUID: UUID :: {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> UUID
+ Foundation.UUID: data UUID
+ Foundation.UUID: fromBinary :: UArray Word8 -> Maybe UUID
+ Foundation.UUID: instance Foundation.Class.Storable.Storable Foundation.UUID.UUID
+ Foundation.UUID: instance Foundation.Class.Storable.StorableFixed Foundation.UUID.UUID
+ Foundation.UUID: instance Foundation.Hashing.Hashable.Hashable Foundation.UUID.UUID
+ Foundation.UUID: instance GHC.Classes.Eq Foundation.UUID.UUID
+ Foundation.UUID: instance GHC.Classes.Ord Foundation.UUID.UUID
+ Foundation.UUID: instance GHC.Show.Show Foundation.UUID.UUID
+ Foundation.UUID: nil :: UUID
- Foundation.Collection: imap :: (InnerFunctor c, Functor f, Element (f a) ~ a, f a ~ c) => (a -> a) -> f a -> f a
+ Foundation.Collection: imap :: (InnerFunctor c, Functor f, Element (f a) ~ a, f a ~ c) => (Element c -> Element c) -> c -> c
- Foundation.Random: getRandomBytes :: MonadRandom m => Int -> m (UArray Word8)
+ Foundation.Random: getRandomBytes :: MonadRandom m => Size Word8 -> m (UArray Word8)
- Foundation.Random: randomGenerate :: RandomGen gen => Int -> gen -> (UArray Word8, gen)
+ Foundation.Random: randomGenerate :: RandomGen gen => Size Word8 -> gen -> (UArray Word8, gen)
- Foundation.System.Entropy: getEntropy :: Int -> IO (UArray Word8)
+ Foundation.System.Entropy: getEntropy :: Size Word8 -> IO (UArray Word8)
- Foundation.System.Info: arch :: Either String Arch
+ Foundation.System.Info: arch :: Either [Char] Arch
- Foundation.System.Info: os :: Either String OS
+ Foundation.System.Info: os :: Either [Char] OS

Files

Foundation/Array/Boxed.hs view
@@ -425,7 +425,7 @@  splitOn ::  (ty -> Bool) -> Array ty -> [Array ty] splitOn predicate vec-    | len == Size 0 = []+    | len == Size 0 = [mempty]     | otherwise     = loop (Offset 0) (Offset 0)   where     !len = lengthSize vec
Foundation/Array/Chunked/Unboxed.hs view
@@ -116,13 +116,7 @@       A.unsafeFreeze a  vToList :: PrimType ty => ChunkedUArray ty -> [ty]-vToList (ChunkedUArray a) = loop (C.length a) 0 mempty-  where-    -- TODO: Rewrite this to use something like a `DList`-    -- to avoid the expensive `mappend`.-    loop len !acc l = case acc >= len of-      True  -> l-      False -> loop len (acc+1) ((toList (A.unsafeIndex a acc)) <> l)+vToList (ChunkedUArray a) = mconcat $ toList $ toList <$> a  null :: PrimType ty => ChunkedUArray ty -> Bool null (ChunkedUArray array) =@@ -314,8 +308,8 @@ uncons :: PrimType ty => ChunkedUArray ty -> Maybe (ty, ChunkedUArray ty) uncons v = second fromList <$> (C.uncons $ toList v) -snoc :: PrimType ty => ChunkedUArray ty -> ty -> ChunkedUArray ty-snoc (ChunkedUArray inner) el = ChunkedUArray $ runST $ do+cons :: PrimType ty => ty -> ChunkedUArray ty -> ChunkedUArray ty+cons el (ChunkedUArray inner) = ChunkedUArray $ runST $ do   let newLen = (Size $ C.length inner + 1)   newArray   <- A.new newLen   let single = fromList [el]@@ -323,8 +317,8 @@   A.unsafeCopyAtRO newArray (Offset 1) inner (Offset 0) (Size $ C.length inner)   A.unsafeFreeze newArray -cons :: PrimType ty => ty -> ChunkedUArray ty -> ChunkedUArray ty-cons el (ChunkedUArray inner) = ChunkedUArray $ runST $ do+snoc :: PrimType ty => ChunkedUArray ty -> ty -> ChunkedUArray ty+snoc (ChunkedUArray inner) el = ChunkedUArray $ runST $ do   newArray   <- A.new (Size $ C.length inner + 1)   let single = fromList [el]   A.unsafeCopyAtRO newArray (Offset 0) inner (Offset 0) (Size $ C.length inner)
Foundation/Array/Unboxed.hs view
@@ -578,8 +578,8 @@     | k == end   = (# r, empty #)     | k == start = (# empty, r #)     | otherwise  =-        (# UVecBA start (offsetAsSize k) pinst ba-        ,  UVecBA (start `offsetPlusE` (offsetAsSize k)) (len - offsetAsSize k) pinst ba+        (# UVecBA start (offsetAsSize k - offsetAsSize start) pinst ba+        ,  UVecBA k     (len - (offsetAsSize k - offsetAsSize start)) pinst ba         #)   where     !end = start `offsetPlusE` len@@ -590,8 +590,9 @@ splitElem !ty r@(UVecAddr start len fptr)     | k == end  = (# r, empty #)     | otherwise =-        (# UVecAddr start (offsetAsSize k) fptr-        ,  UVecAddr (start `offsetPlusE` offsetAsSize k) (len - offsetAsSize k) fptr #)+        (# UVecAddr start (offsetAsSize k - offsetAsSize start) fptr+        ,  UVecAddr k     (len - (offsetAsSize k - offsetAsSize start)) fptr+        #)   where     !(Ptr addr) = withFinalPtrNoTouch fptr id     !end = start `offsetPlusE` len@@ -614,7 +615,7 @@  splitOn :: PrimType ty => (ty -> Bool) -> UArray ty -> [UArray ty] splitOn xpredicate ivec-    | len == 0  = []+    | len == 0  = [mempty]     | otherwise = runST $ unsafeIndexer ivec (go ivec xpredicate)   where     !len = length ivec@@ -923,7 +924,7 @@             | sIdx == endOfs = return ()             | otherwise      = do                 let !(W8# !w)      = getAt sIdx-                    (# wHi, wLo #) = Base16.convertByte w+                    (# wHi, wLo #) = Base16.unsafeConvertByte w                 unsafeWrite ma dIdx     (W8# wHi)                 unsafeWrite ma (dIdx+1) (W8# wLo)                 loop (dIdx + 2) (sIdx+1)
+ Foundation/Check.hs view
@@ -0,0 +1,132 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE OverloadedStrings #-}+module Foundation.Check+    ( Gen+    , Arbitrary(..)+    -- test+    , Test(..)+    , testName+    -- * Property+    , Property(..)+    , IsProperty(..)+    , (===)+    -- * As Program+    , defaultMain+    ) where++import           Foundation.Internal.Base+import           Foundation.Collection+import           Foundation.Numerical+import           Foundation.String+import           Foundation.IO.Terminal+import           Foundation.Check.Gen+import           Foundation.Check.Arbitrary+import           Foundation.Check.Property+import           Foundation.Monad+import           Control.Exception (evaluate, SomeException)+import           System.Exit++-- different type of tests+data Test where+    -- Unit test+    Unit     :: String -> IO () -> Test+    -- Property test+    Property :: IsProperty prop => String -> prop -> Test+    -- Multiples tests grouped together+    Group    :: String -> [Test] -> Test++-- | Name of a test+testName :: Test -> String+testName (Unit s _)     = s+testName (Property s _) = s+testName (Group s _)    = s++data Context = Context+    { contextLevel  :: !Word+    , contextGroups :: [String]+    , contextSeed   :: !Word64+    }++appendContext :: String -> Context -> Context+appendContext s ctx = ctx+    { contextLevel = 1 + contextLevel ctx+    , contextGroups = s : contextGroups ctx+    }++data PropertyResult =+      PropertySuccess+    | PropertyFailed  String+    deriving (Show,Eq)++data TestResult =+      PropertyResult String Word64      PropertyResult+    | GroupResult    String HasFailures [TestResult]+    deriving (Show)++type HasFailures = Word++nbFail :: TestResult -> HasFailures+nbFail (PropertyResult _ _ (PropertyFailed _)) = 1+nbFail (PropertyResult _ _ PropertySuccess)    = 0+nbFail (GroupResult    _ t _)                  = t++runProp :: Context -> String -> Property -> IO TestResult+runProp ctx s prop = do+    (\(e, i) -> PropertyResult s i e) <$> iterProp 0+  where+    nbTests = 100+    iterProp :: Word64 -> IO (PropertyResult, Word64)+    iterProp i+        | i == nbTests = return (PropertySuccess, nbTests)+        | otherwise    = do+            r <- toResult i+            case r of+                PropertyFailed e -> return (PropertyFailed e, i)+                PropertySuccess  -> iterProp (i+1)+    toResult :: Word64 -> IO PropertyResult+    toResult it =+                (propertyToResult <$> evaluate (runGen (unProp prop) (rngIt it) params))+        `catch` (\(e :: SomeException) -> return $ PropertyFailed (fromList $ show e))++    propertyToResult False = PropertyFailed "property failed"+    propertyToResult True  = PropertySuccess++    !rngIt  = genRng (contextSeed ctx) (s : contextGroups ctx)+    !params = GenParams {}++-- | Run tests+defaultMain :: Test -> IO ()+defaultMain test = do+    -- parse arguments+    --let arguments = [ "seed", "j" ]+    let seed = 10++    let context = Context { contextLevel  = 0+                          , contextGroups = []+                          , contextSeed   = seed+                          }++    printHeader context+    tr <- runTest context test+    if nbFail tr > 0+        then putStrLn (fromList (show $ nbFail tr) <> " failure(s)") >> exitFailure+        else putStrLn "Success" >> exitSuccess+  where+    printHeader ctx = do+        putStrLn ("seed: " <> fromList (show (contextSeed ctx))) -- TODO hexadecimal++    runTest :: Context -> Test -> IO TestResult+    runTest ctx (Group s l) = do+        putStrLn s+        results <- mapM (runTest (appendContext s ctx)) l+        return $ GroupResult s (foldl' (+) 0 $ fmap nbFail results) results+    runTest ctx (Property name prop) = do+        v <- runProp ctx name (property prop)+        putStrLn $ fromList (show v)+        return v++    runTest _ (Unit _ _) = do+        error "not implemented"
+ Foundation/Check/Arbitrary.hs view
@@ -0,0 +1,60 @@+module Foundation.Check.Arbitrary+    ( Arbitrary(..)+    ) where++import           Foundation.Internal.Base+import           Foundation.Internal.Natural+import           Foundation.Check.Gen+import           Foundation.Random++-- | How to generate an arbitrary value for 'a'+class Arbitrary a where+    arbitrary :: Gen a++arbitraryBounded :: Bounded b => Gen b+arbitraryBounded = undefined++instance Arbitrary Int where+    arbitrary = genWithRng getRandomPrimType+instance Arbitrary Integer where+    arbitrary = undefined+instance Arbitrary Natural where+    arbitrary = undefined+instance Arbitrary Word64 where+    arbitrary = genWithRng getRandomPrimType+instance Arbitrary Word32 where+    arbitrary = genWithRng getRandomPrimType+instance Arbitrary Word16 where+    arbitrary = genWithRng getRandomPrimType+instance Arbitrary Word8 where+    arbitrary = genWithRng getRandomPrimType+instance Arbitrary Int64 where+    arbitrary = genWithRng getRandomPrimType+instance Arbitrary Int32 where+    arbitrary = genWithRng getRandomPrimType+instance Arbitrary Int16 where+    arbitrary = genWithRng getRandomPrimType+instance Arbitrary Int8 where+    arbitrary = genWithRng getRandomPrimType+instance Arbitrary Char where+    arbitrary = genWithRng getRandomPrimType+instance Arbitrary Bool where+    arbitrary = undefined -- arbitrary++--instance Arbitrary a => Arbitrary (Maybe a) where++instance (Arbitrary a, Arbitrary b)+    => Arbitrary (a,b) where+    arbitrary = (,) <$> arbitrary <*> arbitrary+instance (Arbitrary a, Arbitrary b, Arbitrary c)+    => Arbitrary (a,b,c) where+    arbitrary = (,,) <$> arbitrary <*> arbitrary <*> arbitrary+instance (Arbitrary a, Arbitrary b, Arbitrary c, Arbitrary d)+    => Arbitrary (a,b,c,d) where+    arbitrary = (,,,) <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary+instance (Arbitrary a, Arbitrary b, Arbitrary c, Arbitrary d, Arbitrary e)+    => Arbitrary (a,b,c,d,e) where+    arbitrary = (,,,,) <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary+instance (Arbitrary a, Arbitrary b, Arbitrary c, Arbitrary d, Arbitrary e, Arbitrary f)+    => Arbitrary (a,b,c,d,e,f) where+    arbitrary = (,,,,,) <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
+ Foundation/Check/Gen.hs view
@@ -0,0 +1,73 @@+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE OverloadedStrings #-}+module Foundation.Check.Gen+    ( Gen+    , runGen+    , GenParams(..)+    , genRng+    , genWithRng+    ) where++import           Foundation.Internal.Base+import           Foundation.Collection+import           Foundation.Random+import           Foundation.String+import           Foundation.Numerical+import           Foundation.Hashing.SipHash+import           Foundation.Hashing.Hasher+import qualified Foundation.Array.Unboxed as A++data GenParams = GenParams+    {+    }++newtype GenRng = GenRng RNGv1++type GenSeed = Word64++genRng :: GenSeed -> [String] -> (Word64 -> GenRng)+genRng seed groups = \iteration -> genRngNewNoFail $ A.unsafeRecast $ fromList [w1,w2,w3,iteration]+  where+    w1 = rngSeed+    w2 = rngSeed * 2+    w3 = rngSeed * 4++    (SipHash rngSeed) = hashEnd $ hashMixBytes hashData iHashState+    hashData = toBytes UTF8 $ intercalate "::" (reverse groups)+    iHashState :: Sip1_3+    iHashState = hashNewParam (SipKey seed 0x12345678)++genRngNewNoFail :: A.UArray Word8 -> GenRng+genRngNewNoFail = maybe (error "impossible") GenRng . randomNewFrom++genGenerator :: GenRng -> (GenRng, GenRng)+genGenerator (GenRng rng) =+    let (newSeed, rngNext) = randomGenerate 32 rng+     in (genRngNewNoFail newSeed, GenRng rngNext)++-- | Generator monad+newtype Gen a = Gen { runGen :: GenRng -> GenParams -> a }++instance Functor Gen where+    fmap f g = Gen (\rng params -> f (runGen g rng params))++instance Applicative Gen where+    pure a     = Gen (\_ _ -> a)+    fab <*> fa = Gen $ \rng params ->+        let (r1,r2) = genGenerator rng+            ab      = runGen fab r1 params+            a       = runGen fa r2 params+         in ab a++instance Monad Gen where+    return a  = Gen (\_ _ -> a)+    ma >>= mb = Gen $ \rng params ->+            let (r1,r2) = genGenerator rng+                a       = runGen ma r1 params+             in runGen (mb a) r2 params++genWithRng :: forall a . (forall randomly . MonadRandom randomly => randomly a) -> Gen a+genWithRng f = Gen $ \(GenRng rng) _ ->+    let (a, _) = withRandomGenerator rng f in a
+ Foundation/Check/Property.hs view
@@ -0,0 +1,33 @@+module Foundation.Check.Property+    ( Property(..)+    , IsProperty+    , property+    -- * Properties+    , forAll+    , (===)+    ) where++import Foundation.Internal.Base+import Foundation.Check.Gen+import Foundation.Check.Arbitrary++class IsProperty p where+    property :: p -> Property++instance IsProperty Bool where+    property b = Prop (pure b)+instance IsProperty Property where+    property p = p -- (Prop result) = Prop . return $ result+instance IsProperty prop => IsProperty (Gen prop) where+    property mp = Prop (mp >>= \p -> unProp (property p))+instance (Arbitrary a, IsProperty prop) => IsProperty (a -> prop) where+    property p = forAll arbitrary p++data Property = Prop { unProp :: Gen Bool }++forAll :: IsProperty prop => Gen a -> (a -> prop) -> Property+forAll generator tst = Prop (generator >>= \a -> unProp (property (tst a)))++(===) :: Eq a => a -> a -> Property+(===) a b = Prop (pure (a == b))+infix 4 ===
Foundation/Class/Storable.hs view
@@ -10,13 +10,21 @@ --  {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}  module Foundation.Class.Storable     ( Storable(..)     , StorableFixed(..) +      -- * Ptr     , Ptr, plusPtr, castPtr+      -- * offset based helper     , peekOff, pokeOff+      -- * Collection+    , peekArray+    , peekArrayEndedBy+    , pokeArray+    , pokeArrayEndedBy     ) where  import GHC.Types (Double, Float)@@ -29,6 +37,8 @@ import Foundation.Internal.Base import Foundation.Internal.Types import Foundation.Internal.Proxy+import Foundation.Collection+import Foundation.Collection.Buildable (builderLift) import Foundation.Primitive.Types import Foundation.Primitive.Endianness import Foundation.Numerical@@ -61,6 +71,42 @@ -- | like `poke` but at a given offset. pokeOff :: StorableFixed a => Ptr a -> Offset a -> a -> IO () pokeOff ptr off = poke (ptr `plusPtr` offsetAsSize off)++peekArray :: (Buildable col, StorableFixed (Element col))+          => Size (Element col) -> Ptr (Element col) -> IO col+peekArray (Size s) = build 64 . builder 0+  where+    builder off ptr+      | off == s = return ()+      | otherwise = do+          v <- builderLift (peekOff ptr (Offset off))+          append v+          builder (off + 1) ptr++peekArrayEndedBy :: (Buildable col, StorableFixed (Element col), Eq (Element col), Show (Element col))+                 => Element col -> Ptr (Element col) -> IO col+peekArrayEndedBy term = build 64 . builder 0+  where+    builder off ptr = do+      v <- builderLift $ peekOff ptr off+      if term == v+        then return ()+        else append v >> builder (off + (Offset 1)) ptr++pokeArray :: (Sequential col, StorableFixed (Element col))+          => Ptr (Element col) -> col -> IO ()+pokeArray ptr arr =+    forM_ (z [0..] arr) $ \(i, e) ->+        pokeOff ptr (Offset i) e+  where+    z :: (Sequential col, Collection col) => [Int] -> col -> [(Int, Element col)]+    z = zip++pokeArrayEndedBy :: (Sequential col, StorableFixed (Element col))+                 => Element col -> Ptr (Element col) -> col -> IO ()+pokeArrayEndedBy term ptr col = do+    pokeArray ptr col+    pokeOff ptr (Offset $ length col) term  instance Storable CChar where     peek (Ptr addr) = primAddrRead addr (Offset 0)
Foundation/Collection.hs view
@@ -15,6 +15,11 @@     , Element     , InnerFunctor(..)     , Foldable(..)+    , Mappable(..)+    , traverse_+    , mapM_+    , forM+    , forM_     , Collection(..)     , NonEmpty     , getNonEmpty@@ -40,5 +45,6 @@ import           Foundation.Collection.Mutable import           Foundation.Collection.Collection import           Foundation.Collection.Sequential+import           Foundation.Collection.Mappable import           Foundation.Collection.Zippable import           Foundation.Collection.Copy
Foundation/Collection/Buildable.hs view
@@ -11,6 +11,7 @@     ( Buildable(..)     , Builder(..)     , BuildingState(..)+    , builderLift     ) where  import           Foundation.Array.Unboxed@@ -21,6 +22,7 @@ import           Foundation.Internal.Base import           Foundation.Primitive.Monad import           Foundation.Boot.Builder+import           Foundation.Internal.MonadTrans  -- $setup -- >>> import Control.Monad.ST@@ -53,6 +55,13 @@           => Int -- ^ Size of a chunk           -> Builder col (Mutable col) (Step col) prim ()           -> prim col++builderLift :: (Buildable c, PrimMonad prim)+            => prim a+            -> Builder c (Mutable c) (Step c) prim a+builderLift f = Builder $ State $ \(i, st) -> do+    ret <- f+    return (ret, (i, st))  instance PrimType ty => Buildable (UArray ty) where     type Mutable (UArray ty) = MUArray ty
Foundation/Collection/InnerFunctor.hs view
@@ -12,7 +12,7 @@ -- | A monomorphic functor that maps the inner values to values of the same type class InnerFunctor c where     imap :: (Element c -> Element c) -> c -> c-    default imap :: (Functor f, Element (f a) ~ a, f a ~ c) => (a -> a) -> f a -> f a+    default imap :: (Functor f, Element (f a) ~ a, f a ~ c) => (Element c -> Element c) -> c -> c     imap = fmap  instance InnerFunctor [a]
Foundation/Collection/List.hs view
@@ -21,7 +21,7 @@  -- | Simple helper to split a list repeatly when the predicate match wordsWhen     :: (x -> Bool) -> [x] -> [[x]]-wordsWhen _ [] = []+wordsWhen _ [] = [[]] wordsWhen p is = loop is   where     loop s =
+ Foundation/Collection/Mappable.hs view
@@ -0,0 +1,104 @@+-- |+-- Module      : Foundation.Primitive.Mappable+-- License     : BSD-style+-- Maintainer  : Nicolas Di Prima <nicolas@primetype.co.uk>+-- Stability   : experimental+-- Portability : portable+--+-- Class of collection that can be traversed from left to right,+-- performing an action on each element.+--+module Foundation.Collection.Mappable+    ( Mappable(..)+    , sequence_+    , traverse_+    , mapM_+    , forM+    , forM_+    ) where++import           Foundation.Internal.Base+import qualified Data.Traversable+import           Foundation.Array.Boxed (Array)++-- | Functors representing data structures that can be traversed from+-- left to right.+--+-- Mostly like base's `Traversable` but applied to collections only.+--+class Functor collection => Mappable collection where+    {-# MINIMAL traverse | sequenceA #-}++    -- | Map each element of a structure to an action, evaluate these actions+    -- from left to right, and collect the results. For a version that ignores+    -- the results see 'Foundation.Collection.traverse_'.+    traverse :: Applicative f => (a -> f b)+                              -> collection a+                              -> f (collection b)+    traverse f = sequenceA . fmap f++    -- | Evaluate each actions of the given collections, from left to right,+    -- and collect the results. For a version that ignores the results, see+    -- `Foundation.Collection.sequenceA_`+    sequenceA :: Applicative f => collection (f a)+                               -> f (collection a)+    sequenceA = traverse id++    -- | Map each element of the collection to an action, evaluate these actions+    -- from left to right, and collect the results. For a version that ignores+    -- the results see 'Foundation.Collection.mapM_'.+    mapM :: (Applicative m, Monad m) => (a -> m b) -> collection a -> m (collection b)+    mapM = traverse++    -- | Evaluate each actions of the given collections, from left to right,+    -- and collect the results. For a version that ignores the results, see+    -- `Foundation.Collection.sequence_`+    sequence :: (Applicative m, Monad m) => collection (m a) -> m (collection a)+    sequence = sequenceA++-- | Map each element of a collection to an action, evaluate these+-- actions from left to right, and ignore the results. For a version+-- that doesn't ignore the results see 'Foundation.Collection.traverse`+traverse_ :: (Mappable col, Applicative f) => (a -> f b) -> col a -> f ()+traverse_ f col = traverse f col *> pure ()++-- | Evaluate each action in the collection from left to right, and+-- ignore the results. For a version that doesn't ignore the results+-- see 'Foundation.Collection.sequenceA'.+sequenceA_ :: (Mappable col, Applicative f) => col (f a) -> f ()+sequenceA_ col = sequenceA col *> pure ()++-- | Map each element of a collection to a monadic action, evaluate+-- these actions from left to right, and ignore the results. For a+-- version that doesn't ignore the results see+-- 'Foundation.Collection.mapM'.+mapM_ :: (Mappable col, Applicative m, Monad m) => (a -> m b) -> col a -> m ()+mapM_ f c = mapM f c *> return ()++-- | Evaluate each monadic action in the collection from left to right,+-- and ignore the results. For a version that doesn't ignore the+-- results see 'Foundation.Collection.sequence'.+sequence_ :: (Mappable col, Applicative m, Monad m) => col (m a) -> m ()+sequence_ c = sequence c *> return ()++-- | 'forM' is 'mapM' with its arguments flipped. For a version that+-- ignores the results see 'Foundation.Collection.forM_'.+forM :: (Mappable col, Applicative m, Monad m) => col a -> (a -> m b) -> m (col b)+forM = flip mapM++-- | 'forM_' is 'mapM_' with its arguments flipped. For a version that+-- doesn't ignore the results see 'Foundation.Collection.forM'.+forM_ :: (Mappable col, Applicative m, Monad m) => col a -> (a -> m b) -> m ()+forM_ = flip mapM_++----------------------------+-- Foldable instances+----------------------------++instance Mappable [] where+    {-# INLINE traverse #-}+    traverse = Data.Traversable.traverse++instance Mappable Array where+    -- | TODO: to optimise+    traverse f arr = fromList <$> traverse f (toList arr)
Foundation/Hashing/FNV.hs view
@@ -80,28 +80,36 @@  instance Hasher FNV1_32 where     type HashResult FNV1_32 = FNV1Hash32+    type HashInitParam FNV1_32 = Word     hashNew = FNV1_32 0+    hashNewParam w = FNV1_32 w     hashEnd (FNV1_32 w) = FNV1Hash32 (Prelude.fromIntegral w)     hashMix8 = fnv1_32_Mix8     hashMixBytes = fnv1_32_mixBa  instance Hasher FNV1a_32 where     type HashResult FNV1a_32 = FNV1Hash32+    type HashInitParam FNV1a_32 = Word     hashNew = FNV1a_32 0+    hashNewParam w = FNV1a_32 w     hashEnd (FNV1a_32 w) = FNV1Hash32 (Prelude.fromIntegral w)     hashMix8 = fnv1a_32_Mix8     hashMixBytes = fnv1a_32_mixBa  instance Hasher FNV1_64 where     type HashResult FNV1_64 = FNV1Hash64+    type HashInitParam FNV1_64 = Word64     hashNew = FNV1_64 0xcbf29ce484222325+    hashNewParam w = FNV1_64 w     hashEnd (FNV1_64 w) = FNV1Hash64 (Prelude.fromIntegral w)     hashMix8 = fnv1_64_Mix8     hashMixBytes = fnv1_64_mixBa  instance Hasher FNV1a_64 where     type HashResult FNV1a_64 = FNV1Hash64+    type HashInitParam FNV1a_64 = Word64     hashNew = FNV1a_64 0xcbf29ce484222325+    hashNewParam w = FNV1a_64 w     hashEnd (FNV1a_64 w) = FNV1Hash64 (Prelude.fromIntegral w)     hashMix8 = fnv1a_64_Mix8     hashMixBytes = fnv1a_64_mixBa
Foundation/Hashing/Hasher.hs view
@@ -17,13 +17,19 @@ -- The class allow to define faster mixing function that works on -- bigger Word size and any unboxed array of any PrimType elements class Hasher st where-    {-# MINIMAL hashNew, hashMix8, hashEnd #-}+    {-# MINIMAL hashNew, hashNewParam, hashMix8, hashEnd #-}      -- | Associate type when finalizing the state with 'hashEnd'     type HashResult st +    -- | Associate type when initializing the state (e.g. a Key or seed)+    type HashInitParam st+     -- | Create a new Hashing context     hashNew :: st++    -- | Create a new Hashing context+    hashNewParam :: HashInitParam st -> st      -- | Finalize the state and returns the hash result     hashEnd :: st -> HashResult st
Foundation/Hashing/SipHash.hs view
@@ -13,6 +13,7 @@ {-# LANGUAGE UnboxedTuples #-} module Foundation.Hashing.SipHash     ( SipKey(..)+    , SipHash(..)     , Sip1_3     , Sip2_4     ) where@@ -46,7 +47,9 @@  instance Hasher Sip2_4 where     type HashResult Sip2_4      = SipHash+    type HashInitParam Sip2_4   = SipKey     hashNew                     = Sip2_4 $ newSipState (SipKey 0 0)+    hashNewParam key            = Sip2_4 $ newSipState key     hashEnd (Sip2_4 st)         = finish 2 4 st     hashMix8 w (Sip2_4 st)      = Sip2_4 $ mix8 2 w st     hashMix32 w (Sip2_4 st)     = Sip2_4 $ mix32 2 w st@@ -55,7 +58,9 @@  instance Hasher Sip1_3 where     type HashResult Sip1_3      = SipHash+    type HashInitParam Sip1_3   = SipKey     hashNew                     = Sip1_3 $ newSipState (SipKey 0 0)+    hashNewParam key            = Sip1_3 $ newSipState key     hashEnd (Sip1_3 st)         = finish 1 3 st     hashMix8 w (Sip1_3 st)      = Sip1_3 $ mix8 1 w st     hashMix32 w (Sip1_3 st)     = Sip1_3 $ mix32 1 w st
Foundation/Internal/Base.hs view
@@ -82,6 +82,7 @@ import qualified GHC.Exts import qualified GHC.Generics import qualified GHC.Ptr+import           GHC.Exts (fromString)  -- | Only to use internally for internal error cases internalError :: [Prelude.Char] -> a
+ Foundation/List/SList.hs view
@@ -0,0 +1,187 @@+-- |+-- Module      : Foundation.List.SList+-- License     : BSD-style+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>+-- Stability   : experimental+-- Portability : portable+--+-- A Nat-sized list abstraction+--+-- Using this module is limited to GHC 7.10 and above.+--+{-# LANGUAGE KindSignatures            #-}+{-# LANGUAGE DataKinds                 #-}+{-# LANGUAGE GADTs                     #-}+{-# LANGUAGE TypeOperators             #-}+{-# LANGUAGE TypeFamilies              #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE ScopedTypeVariables       #-}+{-# LANGUAGE UndecidableInstances      #-}+module Foundation.List.SList+    ( SList+    , toSList+    , unSList+    , length+    , create+    , createFrom+    , empty+    , singleton+    , uncons+    , cons+    , map+    , elem+    , foldl+    , append+    , minimum+    , maximum+    , head+    , tail+    , take+    , drop+    , zip, zip3, zip4, zip5+    , zipWith, zipWith3, zipWith4, zipWith5+    , replicateM+    ) where++import           Data.Proxy+import           Foundation.Internal.Base+import           Foundation.Primitive.Nat+import           Foundation.Numerical+import qualified Prelude+import qualified Control.Monad as M (replicateM)++impossible :: a+impossible = error "SList: internal error: the impossible happened"++newtype SList (n :: Nat) a = SList { unSList :: [a] }++toSList :: forall (n :: Nat) a . (KnownNat n, NatWithinBound Int n) => [a] -> Maybe (SList n a)+toSList l+    | expected == Prelude.fromIntegral (Prelude.length l) = Just (SList l)+    | otherwise                                           = Nothing+  where+    expected = natValInt (Proxy :: Proxy n)++replicateM :: forall (n :: Nat) m a . (n <= 0x100000, Monad m, KnownNat n) => m a -> m (SList n a)+replicateM action = SList <$> M.replicateM (Prelude.fromIntegral $ natVal (Proxy :: Proxy n)) action++uncons :: CmpNat n 0 ~ 'GT => SList n a -> (a, SList (n-1) a)+uncons (SList (x:xs)) = (x, SList xs)+uncons _ = impossible++cons :: a -> SList n a -> SList (n+1) a+cons a (SList l) = SList (a : l)++empty :: SList 0 a+empty = SList []++length :: forall a (n :: Nat) . (KnownNat n, NatWithinBound Int n) => SList n a -> Int+length _ = natValInt (Proxy :: Proxy n)++create :: forall a (n :: Nat) . KnownNat n => (Integer -> a) -> SList n a+create f = SList $ Prelude.map f [0..(len-1)]+  where+    len = natVal (Proxy :: Proxy n)++createFrom :: forall a (n :: Nat) (start :: Nat) . (KnownNat n, KnownNat start)+           => Proxy start -> (Integer -> a) -> SList n a+createFrom p f = SList $ Prelude.map f [idx..(idx+len)]+  where+    len = natVal (Proxy :: Proxy n)+    idx = natVal p++singleton :: a -> SList 1 a+singleton a = SList [a]++elem :: Eq a => a -> SList n a -> Bool+elem a (SList l) = Prelude.elem a l++append :: SList n a -> SList m a -> SList (n+m) a+append (SList l1) (SList l2) = SList (l1 <> l2)++maximum :: (Ord a, CmpNat n 0 ~ 'GT) => SList n a -> a+maximum (SList l) = Prelude.maximum l++minimum :: (Ord a, CmpNat n 0 ~ 'GT) => SList n a -> a+minimum (SList l) = Prelude.minimum l++head :: CmpNat n 0 ~ 'GT => SList n a -> a+head (SList (x:_)) = x+head _ = impossible++tail :: CmpNat n 0 ~ 'GT => SList n a -> SList (n-1) a+tail (SList (_:xs)) = SList xs+tail _ = impossible++take :: forall a (m :: Nat) (n :: Nat) . (KnownNat m, NatWithinBound Int m, m <= n) => SList n a -> SList m a+take (SList l) = SList (Prelude.take n l)+  where n = natValInt (Proxy :: Proxy m)++drop :: forall a d (m :: Nat) (n :: Nat) . (KnownNat d, NatWithinBound Int d, (n - m) ~ d, m <= n) => SList n a -> SList m a+drop (SList l) = SList (Prelude.drop n l)+  where n = natValInt (Proxy :: Proxy d)++map :: (a -> b) -> SList n a -> SList n b+map f (SList l) = SList (Prelude.map f l)++foldl :: (b -> a -> b) -> b -> SList n a -> b+foldl f acc (SList l) = Prelude.foldl f acc l++zip :: SList n a -> SList n b -> SList n (a,b)+zip (SList l1) (SList l2) = SList (Prelude.zip l1 l2)++zip3 :: SList n a -> SList n b -> SList n c -> SList n (a,b,c)+zip3 (SList x1) (SList x2) (SList x3) = SList (loop x1 x2 x3)+  where loop (l1:l1s) (l2:l2s) (l3:l3s) = (l1,l2,l3) : loop l1s l2s l3s+        loop []       _        _        = []+        loop _        _        _        = impossible++zip4 :: SList n a -> SList n b -> SList n c -> SList n d -> SList n (a,b,c,d)+zip4 (SList x1) (SList x2) (SList x3) (SList x4) = SList (loop x1 x2 x3 x4)+  where loop (l1:l1s) (l2:l2s) (l3:l3s) (l4:l4s) = (l1,l2,l3,l4) : loop l1s l2s l3s l4s+        loop []       _        _        _        = []+        loop _        _        _        _        = impossible++zip5 :: SList n a -> SList n b -> SList n c -> SList n d -> SList n e -> SList n (a,b,c,d,e)+zip5 (SList x1) (SList x2) (SList x3) (SList x4) (SList x5) = SList (loop x1 x2 x3 x4 x5)+  where loop (l1:l1s) (l2:l2s) (l3:l3s) (l4:l4s) (l5:l5s) = (l1,l2,l3,l4,l5) : loop l1s l2s l3s l4s l5s+        loop []       _        _        _        _        = []+        loop _        _        _        _        _        = impossible++zipWith :: (a -> b -> x) -> SList n a -> SList n b -> SList n x+zipWith f (SList (v1:vs)) (SList (w1:ws)) = SList (f v1 w1 : unSList (zipWith f (SList vs) (SList ws)))+zipWith _ (SList [])       _ = SList []+zipWith _ _                _ = impossible++zipWith3 :: (a -> b -> c -> x)+         -> SList n a+         -> SList n b+         -> SList n c+         -> SList n x+zipWith3 f (SList (v1:vs)) (SList (w1:ws)) (SList (x1:xs)) =+    SList (f v1 w1 x1 : unSList (zipWith3 f (SList vs) (SList ws) (SList xs)))+zipWith3 _ (SList []) _       _ = SList []+zipWith3 _ _          _       _ = impossible++zipWith4 :: (a -> b -> c -> d -> x)+         -> SList n a+         -> SList n b+         -> SList n c+         -> SList n d+         -> SList n x+zipWith4 f (SList (v1:vs)) (SList (w1:ws)) (SList (x1:xs)) (SList (y1:ys)) =+    SList (f v1 w1 x1 y1 : unSList (zipWith4 f (SList vs) (SList ws) (SList xs) (SList ys)))+zipWith4 _ (SList []) _       _       _ = SList []+zipWith4 _ _          _       _       _ = impossible++zipWith5 :: (a -> b -> c -> d -> e -> x)+         -> SList n a+         -> SList n b+         -> SList n c+         -> SList n d+         -> SList n e+         -> SList n x+zipWith5 f (SList (v1:vs)) (SList (w1:ws)) (SList (x1:xs)) (SList (y1:ys)) (SList (z1:zs)) =+    SList (f v1 w1 x1 y1 z1 : unSList (zipWith5 f (SList vs) (SList ws) (SList xs) (SList ys) (SList zs)))+zipWith5 _ (SList []) _       _       _       _ = SList []+zipWith5 _ _          _       _       _       _ = impossible
Foundation/Monad.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE StandaloneDeriving #-} module Foundation.Monad     ( MonadIO(..)     , MonadFailure(..)@@ -23,13 +24,20 @@ import Control.Monad.Fix import Control.Monad.Zip import Foundation.Internal.Base++#if MIN_VERSION_base(4,6,0) import GHC.Generics (Generic1)+#endif  -- | Identity functor and monad. (a non-strict monad) -- -- @since 4.8.0.0 newtype Identity a = Identity { runIdentity :: a }-    deriving (Eq, Ord, Data, Generic, Generic1, Typeable)+    deriving (Eq, Ord, Data, Generic, Typeable)++#if MIN_VERSION_base(4,6,0)+deriving instance Generic1 Identity+#endif  instance Functor Identity where     fmap f (Identity x) = Identity (f x)
+ Foundation/Network/HostName.hsc view
@@ -0,0 +1,169 @@+-- |+-- Module      : Foundation.Network.HostName+-- License     : BSD-style+-- Maintainer  : Nicolas Di Prima <nicolas@primetype.co.uk>+-- Stability   : experimental+-- Portability : portable+--+-- HostName and HostName info+--+-- > getHostNameInfo "github.com" :: IO (HostNameInfo IPv4)+--+-- > getHostNameInfo "google.com" :: IO (HostNameInfo IPv6)+--+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ForeignFunctionInterface #-}+module Foundation.Network.HostName+    ( HostName(..)+    , HostNameInfo(..)+    , getHostNameInfo+    , getHostNameInfo_+    ) where++import Foundation.Class.Storable+import Foundation.Internal.Base+import Foundation.Internal.Proxy+import Foundation.Hashing (Hashable)+import Foundation.String+import Foundation.Array+import Foundation.Collection.Mappable+import Foundation.Network.IPv4 (IPv4)+import Foundation.Network.IPv6 (IPv6)++import Foundation.System.Bindings.Network++import Foreign.C.String+import Foreign.C.Types+import Foreign.Ptr (nullPtr)+import Control.Concurrent.MVar+import System.IO.Unsafe (unsafePerformIO)++import Control.Monad ((=<<))++#ifdef mingw32_HOST_OS+# include <winsock2.h>+#else+# include <netdb.h>+# include <netinet/in.h>+# include <sys/socket.h>+#endif++-- | HostName+--+newtype HostName = HostName { toString :: String }+  deriving (Eq, Ord, Typeable, Hashable)+instance Show HostName where+    show = show . toString+instance IsString HostName where+    fromString = HostName . fromString++-- | HostName Info+data HostNameInfo address_type = HostNameInfo+    { officialName :: !HostName+        -- ^ official names+    , aliases      :: !(Array HostName)+        -- ^ known aliases+    , addresses    :: !(Array address_type)+        -- ^ known addresses+    } deriving (Show, Eq, Ord, Typeable)++-- | HostName errors+data HostNameError+    = HostNotFound !HostName+        -- ^ the given HostMame was not found+    | NoAssociatedData !HostName+        -- ^ there is not associated info/data to the given HostName+        --+        -- i.e. : no IPv4 info? This might mean you should try IPv6 ?+    | FatalError+        -- ^ getHostNameInfo uses *C* a binding to get the `HostNameInfo`+        --+        -- a fatal error is linked to the underlying *C* function and is not+        -- recoverable.+    | UnknownError !CInt+        -- ^ Unknown Error, `CInt` is the associated error code.+        --+        -- see man gethostbyname for more information+  deriving (Show,Eq,Typeable)++instance Exception HostNameError++-- TODO: move this when we have socket family and domain name...+class SocketFamily a where+    familyCode :: proxy a -> CInt+instance SocketFamily IPv4 where+    familyCode _ = (#const AF_INET)+instance SocketFamily IPv6 where+    familyCode _ = (#const AF_INET6)++-- | get `HostName` info:+--+-- retrieve the official name, the aliases and the addresses associated to this+-- hostname.+--+-- For cross-platform compatibility purpose, this function is using a *C* non+-- re-entrant function `gethostbyname2`. This function is using a `MVar ()` to+-- avoid a race condition and should be safe to use.+--+getHostNameInfo :: (Eq address_type, Storable address_type, SocketFamily address_type)+                => HostName+                -> IO (HostNameInfo address_type)+getHostNameInfo = getHostNameInfo_ Proxy++globalMutex :: MVar ()+globalMutex = unsafePerformIO (newMVar ())+{-# NOINLINE globalMutex #-}++-- | like `getHostNameInfo` but takes a `Proxy` to help with the type checker.+getHostNameInfo_ :: (SocketFamily address_type, Eq address_type, Storable address_type)+                 => Proxy address_type+                 -> HostName+                 -> IO (HostNameInfo address_type)+getHostNameInfo_ p h@(HostName hn) =+    withMVar globalMutex $ \_ ->+    withCString (toList hn) $ \cname -> do+        ptr <- loop $ c_gethostbyname2 cname (familyCode p)++        on <- peekHostName . castPtr =<< peek (castPtr $ offname_ptr ptr)++        as <- getAliases . castPtr =<< peek (castPtr $ aliases_ptr ptr)++        addrs <- getAddresses p . castPtr =<< peek (castPtr $ addr_list ptr)+        return $ HostNameInfo on as addrs+  where+    loop f = do+        ptr <- f+        if ptr /= nullPtr+            then return ptr+            else do+                err <- getHErrno+                case err of+                    _ | err == herr_NoData        -> throwIO $ NoAssociatedData h+                      | err == herr_HostNotFound  -> throwIO $ HostNotFound h+                      | err == herr_TryAgain      -> loop f+                      | err == herr_NoRecovery    -> throwIO FatalError+                      | otherwise                 -> throwIO $ UnknownError err+    offname_ptr = (#ptr struct hostent, h_name)+    aliases_ptr = (#ptr struct hostent, h_aliases)+    addr_list   = (#ptr struct hostent, h_addr_list)++peekHostName :: Ptr Word8 -> IO HostName+peekHostName ptr = HostName . fst . fromBytesLenient <$> peekArrayEndedBy 0x00 ptr++getAliases :: Ptr (Ptr Word8) -> IO (Array HostName)+getAliases ptr = do+    arr <- peekArrayEndedBy nullPtr ptr+    forM arr peekHostName++getAddresses :: Storable address_type+             => Proxy address_type+             -> Ptr (Ptr address_type)+             -> IO (Array address_type)+getAddresses _ ptr = do+    arr <- peekArrayEndedBy nullPtr ptr+    forM arr peek++foreign import ccall safe "gethostbyname2"+    c_gethostbyname2 :: CString -> CInt -> IO (Ptr Word8)
Foundation/Network/IPv4.hs view
@@ -1,8 +1,18 @@+-- |+-- Module      : Foundation.Network.IPv4+-- License     : BSD-style+-- Maintainer  : Nicolas Di Prima <nicolas@primetype.co.uk>+-- Stability   : experimental+-- Portability : portable+--+-- IPv4 data type+-- {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}  module Foundation.Network.IPv4     ( IPv4+    , any, loopback     , fromString, toString     , fromTuple, toTuple     , ipv4Parser@@ -18,7 +28,7 @@ import Foundation.Primitive import Foundation.Bits import Foundation.Parser-import Foundation.Collection+import Foundation.Collection (Sequential, Element, elem)  -- | IPv4 data type newtype IPv4 = IPv4 Word32@@ -33,6 +43,14 @@ instance StorableFixed IPv4 where     size      _ = size      (Proxy :: Proxy Word32)     alignment _ = alignment (Proxy :: Proxy Word32)++-- | "0.0.0.0"+any :: IPv4+any = fromTuple (0,0,0,0)++-- | "127.0.0.1"+loopback :: IPv4+loopback = fromTuple (127,0,0,1)  toString :: IPv4 -> String toString = fromList . toLString
Foundation/Network/IPv6.hs view
@@ -13,6 +13,7 @@  module Foundation.Network.IPv6     ( IPv6+    , any, loopback     , fromString, toString     , fromTuple, toTuple       -- * parsers@@ -35,7 +36,7 @@ import Foundation.Internal.Proxy import Foundation.Primitive import Foundation.Numerical-import Foundation.Collection+import Foundation.Collection (Sequential, Element, length, intercalate, null) import Foundation.Parser import Foundation.String (String) import Foundation.Bits@@ -80,6 +81,14 @@ instance StorableFixed IPv6 where     size      _ = (size      (Proxy :: Proxy Word64)) `scale` 2     alignment _ = alignment (Proxy :: Proxy Word64)++-- | equivalent to `::`+any :: IPv6+any = fromTuple (0,0,0,0,0,0,0,0)++-- | equivalent to `::1`+loopback :: IPv6+loopback = fromTuple (0,0,0,0,0,0,0,1)  -- | serialise to human readable IPv6 --
Foundation/Primitive.hs view
@@ -18,8 +18,14 @@     , ByteSwap     , LE(..), toLE, fromLE     , BE(..), toBE, fromBE++    -- * Integral convertion+    , IntegralUpsize(..)+    , IntegralDownsize(..)+    , IntegralCast(..)     ) where  import Foundation.Primitive.Types import Foundation.Primitive.Monad import Foundation.Primitive.Endianness+import Foundation.Primitive.IntegralConv
Foundation/Primitive/Base16.hs view
@@ -2,26 +2,53 @@ {-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE BangPatterns  #-} module Foundation.Primitive.Base16-    ( convertByte+    ( unsafeConvertByte+    , hexWord16+    , hexWord32     ) where  import GHC.Prim+import GHC.Types+import GHC.Word  -- | Convert a byte value in Word# to two Word#s containing -- the hexadecimal representation of the Word# --+-- The output words# are guaranteed to be included in the 0 to 2^7-1 range+-- -- Note that calling convertByte with a value greater than 256 -- will cause segfault or other horrible effect.-convertByte :: Word# -> (# Word#, Word# #)-convertByte b = (# r tableHi b, r tableLo b #)+unsafeConvertByte :: Word# -> (# Word#, Word# #)+unsafeConvertByte b = (# r tableHi b, r tableLo b #)   where-        r :: Table -> Word# -> Word#-        r (Table !table) index = indexWord8OffAddr# table (word2Int# index)-{-# INLINE convertByte #-}+    r :: Table -> Word# -> Word#+    r (Table !table) index = indexWord8OffAddr# table (word2Int# index)+{-# INLINE unsafeConvertByte #-} +-- | hex word16+hexWord16 :: Word16 -> (Char, Char, Char, Char)+hexWord16 (W16# w) = (toChar w1,toChar w2,toChar w3,toChar w4)+  where+    toChar :: Word# -> Char+    toChar c = C# (chr# (word2Int# c))+    (# w1, w2 #) = unsafeConvertByte (uncheckedShiftRL# w 8#)+    (# w3, w4 #) = unsafeConvertByte (and# w 0xff##)++-- | hex word32+hexWord32 :: Word32 -> (Char, Char, Char, Char, Char, Char, Char, Char)+hexWord32 (W32# w) = (toChar w1,toChar w2,toChar w3,toChar w4+                     ,toChar w5,toChar w6,toChar w7,toChar w8)+  where+    toChar :: Word# -> Char+    toChar c = C# (chr# (word2Int# c))+    (# w1, w2 #) = unsafeConvertByte (uncheckedShiftRL# w 24#)+    (# w3, w4 #) = unsafeConvertByte (and# (uncheckedShiftRL# w 16#) 0xff##)+    (# w5, w6 #) = unsafeConvertByte (and# (uncheckedShiftRL# w 8#) 0xff##)+    (# w7, w8 #) = unsafeConvertByte (and# w 0xff##)+ data Table = Table Addr# -tableLo :: Table+tableLo:: Table tableLo = Table     "0123456789abcdef0123456789abcdef\     \0123456789abcdef0123456789abcdef\
Foundation/Primitive/Endianness.hs view
@@ -18,15 +18,32 @@     , BE(..), toBE, fromBE       -- * Little Endian     , LE(..), toLE, fromLE+      -- * System Endianness+    , Endianness(..)+    , endianness     ) where  import Foundation.Internal.Base import Foundation.Internal.ByteSwap -#if !defined(ARCH_IS_LITTLE_ENDIAN) && !defined(ARCH_IS_BIG_ENDIAN)-import Foundation.System.Info (endianness, Endianness(..))+#ifdef ARCH_IS_UNKNOWN_ENDIAN+import Foreign.Marshal.Alloc (alloca)+import Foreign.Ptr (castPtr)+import Foreign.Storable (poke, peek)+import Data.Word (Word8, Word32)+import System.IO.Unsafe (unsafePerformIO) #endif ++-- #if !defined(ARCH_IS_LITTLE_ENDIAN) && !defined(ARCH_IS_BIG_ENDIAN)+-- import Foundation.System.Info (endianness, Endianness(..))+-- #endif++data Endianness =+      LittleEndian+    | BigEndian+    deriving (Eq, Show)+ -- | Little Endian value newtype LE a = LE { unLE :: a }   deriving (Show, Eq, Typeable)@@ -82,3 +99,27 @@ fromLE (LE a) = if endianness == LittleEndian then a else byteSwap a #endif {-# INLINE fromLE #-}++-- | endianness of the current architecture+endianness :: Endianness+#ifdef ARCH_IS_LITTLE_ENDIAN+endianness = LittleEndian+#elif ARCH_IS_BIG_ENDIAN+endianness = BigEndian+#else+-- ! ARCH_IS_UNKNOWN_ENDIAN+endianness = unsafePerformIO $ bytesToEndianness <$> word32ToByte input+  where+    input :: Word32+    input = 0x01020304+{-# NOINLINE endianness #-}++word32ToByte :: Word32 -> IO Word8+word32ToByte word = alloca $ \wordPtr -> do+         poke wordPtr word+         peek (castPtr wordPtr)++bytesToEndianness :: Word8 -> Endianness+bytesToEndianness 1 = BigEndian+bytesToEndianness _ = LittleEndian+#endif
+ Foundation/Primitive/IntegralConv.hs view
@@ -0,0 +1,260 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE DefaultSignatures     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE UnboxedTuples         #-}+module Foundation.Primitive.IntegralConv+    ( IntegralDownsize(..)+    , IntegralUpsize(..)+    , IntegralCast(..)+    , intToInt64+    , wordToWord64+    , word64ToWord32s+    , word64ToWord+    ) where++#include "MachDeps.h"++import GHC.Types+import GHC.Prim+import GHC.Int+import GHC.Word+import Prelude (Integer, fromIntegral)+import Foundation.Internal.Base+import Foundation.Internal.Natural++#if WORD_SIZE_IN_BITS < 64+import GHC.IntWord64+#endif++-- | Downsize an integral value+class IntegralDownsize a b where+    integralDownsize :: a -> b+    default integralDownsize :: a ~ b => a -> b+    integralDownsize = id++    integralDownsizeCheck :: a -> Maybe b++-- | Upsize an integral value+--+-- The destination type 'b' size need to be greater or equal+-- than the size type of 'a'+class IntegralUpsize a b where+    integralUpsize      :: a -> b++-- | Cast an integral value to another value+-- that have the same representional size+class IntegralCast a b where+    integralCast :: a -> b+    default integralCast :: a ~ b => a -> b+    integralCast = id++integralDownsizeBounded :: forall a b . (Ord a, Bounded b, IntegralDownsize a b, IntegralUpsize b a)+                        => (a -> b)+                        -> a+                        -> Maybe b+integralDownsizeBounded aToB x+    | x < integralUpsize (minBound :: b) && x > integralUpsize (maxBound :: b) = Nothing+    | otherwise                                                                = Just (aToB x)++instance IntegralUpsize Int8 Int16 where+    integralUpsize (I8# i) = I16# i+instance IntegralUpsize Int8 Int32 where+    integralUpsize (I8# i) = I32# i+instance IntegralUpsize Int8 Int64 where+    integralUpsize (I8# i) = intToInt64 (I# i)+instance IntegralUpsize Int8 Int where+    integralUpsize (I8# i) = I# i+instance IntegralUpsize Int8 Integer where+    integralUpsize = fromIntegral++instance IntegralUpsize Int16 Int32 where+    integralUpsize (I16# i) = I32# i+instance IntegralUpsize Int16 Int64 where+    integralUpsize (I16# i) = intToInt64 (I# i)+instance IntegralUpsize Int16 Int where+    integralUpsize (I16# i) = I# i+instance IntegralUpsize Int16 Integer where+    integralUpsize = fromIntegral++instance IntegralUpsize Int32 Int64 where+    integralUpsize (I32# i) = intToInt64 (I# i)+instance IntegralUpsize Int32 Int where+    integralUpsize (I32# i) = I# i+instance IntegralUpsize Int32 Integer where+    integralUpsize = fromIntegral++instance IntegralUpsize Int64 Integer where+    integralUpsize = fromIntegral++instance IntegralUpsize Word8 Word16 where+    integralUpsize (W8# i) = W16# i+instance IntegralUpsize Word8 Word32 where+    integralUpsize (W8# i) = W32# i+instance IntegralUpsize Word8 Word64 where+    integralUpsize (W8# i) = wordToWord64 (W# i)+instance IntegralUpsize Word8 Word where+    integralUpsize (W8# i) = W# i+instance IntegralUpsize Word8 Integer where+    integralUpsize = fromIntegral+instance IntegralUpsize Word8 Natural where+    integralUpsize = fromIntegral++instance IntegralUpsize Word16 Word32 where+    integralUpsize (W16# i) = W32# i+instance IntegralUpsize Word16 Word64 where+    integralUpsize (W16# i) = wordToWord64 (W# i)+instance IntegralUpsize Word16 Word where+    integralUpsize (W16# i) = W# i+instance IntegralUpsize Word16 Integer where+    integralUpsize = fromIntegral+instance IntegralUpsize Word16 Natural where+    integralUpsize = fromIntegral++instance IntegralUpsize Word32 Word64 where+    integralUpsize (W32# i) = wordToWord64 (W# i)+instance IntegralUpsize Word32 Word where+    integralUpsize (W32# i) = W# i+instance IntegralUpsize Word32 Integer where+    integralUpsize = fromIntegral+instance IntegralUpsize Word32 Natural where+    integralUpsize = fromIntegral++instance IntegralUpsize Word64 Integer where+    integralUpsize = fromIntegral+instance IntegralUpsize Word64 Natural where+    integralUpsize = fromIntegral++instance IntegralDownsize Int Int8 where+    integralDownsize      (I# i) = I8# (narrow8Int# i)+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Int Int16 where+    integralDownsize      (I# i) = I16# (narrow16Int# i)+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Int Int32 where+    integralDownsize      (I# i) = I32# (narrow32Int# i)+    integralDownsizeCheck = integralDownsizeBounded integralDownsize++instance IntegralDownsize Word64 Word8 where+    integralDownsize      (W64# i) = W8# (narrow8Word# (word64ToWord# i))+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Word64 Word16 where+    integralDownsize      (W64# i) = W16# (narrow16Word# (word64ToWord# i))+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Word64 Word32 where+    integralDownsize      (W64# i) = W32# (narrow32Word# (word64ToWord# i))+    integralDownsizeCheck = integralDownsizeBounded integralDownsize++instance IntegralDownsize Word32 Word8 where+    integralDownsize      (W32# i) = W8# (narrow8Word# i)+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Word32 Word16 where+    integralDownsize      (W32# i) = W16# (narrow16Word# i)+    integralDownsizeCheck = integralDownsizeBounded integralDownsize++instance IntegralDownsize Word16 Word8 where+    integralDownsize      (W16# i) = W8# (narrow8Word# i)+    integralDownsizeCheck = integralDownsizeBounded integralDownsize++instance IntegralDownsize Integer Int8 where+    integralDownsize = fromIntegral+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Integer Int16 where+    integralDownsize = fromIntegral+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Integer Int32 where+    integralDownsize = fromIntegral+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Integer Int64 where+    integralDownsize = fromIntegral+    integralDownsizeCheck = integralDownsizeBounded integralDownsize++instance IntegralDownsize Integer Word8 where+    integralDownsize = fromIntegral+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Integer Word16 where+    integralDownsize = fromIntegral+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Integer Word32 where+    integralDownsize = fromIntegral+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Integer Word64 where+    integralDownsize = fromIntegral+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Integer Natural where+    integralDownsize i+        | i >= 0    = fromIntegral i+        | otherwise = 0+    integralDownsizeCheck i+        | i >= 0    = Just (fromIntegral i)+        | otherwise = Nothing++instance IntegralDownsize Natural Word8 where+    integralDownsize = fromIntegral+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Natural Word16 where+    integralDownsize = fromIntegral+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Natural Word32 where+    integralDownsize = fromIntegral+    integralDownsizeCheck = integralDownsizeBounded integralDownsize+instance IntegralDownsize Natural Word64 where+    integralDownsize = fromIntegral+    integralDownsizeCheck = integralDownsizeBounded integralDownsize++instance IntegralCast Word Int where+    integralCast (W# w) = I# (word2Int# w)+instance IntegralCast Int Word where+    integralCast (I# i) = W# (int2Word# i)+instance IntegralCast Word64 Int64 where+#if WORD_SIZE_IN_BITS == 64+    integralCast (W64# i) = I64# (word2Int# i)+#else+    integralCast (W64# i) = I64# (word64ToInt64# i)+#endif+instance IntegralCast Int64 Word64 where+#if WORD_SIZE_IN_BITS == 64+    integralCast (I64# i) = W64# (int2Word# i)+#else+    integralCast (I64# i) = W64# (int64ToWord64# i)+#endif++-- missing word8, word16, word32, word64+-- instance IntegralCast Word8 Int8 where+-- instance IntegralCast Int8 Word8 where++intToInt64 :: Int -> Int64+#if WORD_SIZE_IN_BITS == 64+intToInt64 (I# i) = I64# i+#else+intToInt64 (I# i) = I64# (intToInt64# i)+#endif++wordToWord64 :: Word -> Word64+#if WORD_SIZE_IN_BITS == 64+wordToWord64 (W# i) = W64# i+#else+wordToWord64 (W# i) = W64# (wordToWord64# i)+#endif++word64ToWord :: Word64 -> Word+#if WORD_SIZE_IN_BITS == 64+word64ToWord (W64# i) = W# i+#else+word64ToWord (W64# i) = W# (word64ToWord# i)+#endif++#if WORD_SIZE_IN_BITS == 64+word64ToWord# :: Word# -> Word#+word64ToWord# i = i+{-# INLINE word64ToWord# #-}+#endif++#if WORD_SIZE_IN_BITS == 64+word64ToWord32s :: Word64 -> (# Word32, Word32 #)+word64ToWord32s (W64# w) = (# W32# (uncheckedShiftRL# w 32#), W32# (narrow32Word# w) #)+#else+word64ToWord32s :: Word64 -> (# Word32, Word32 #)+word64ToWord32s (W64# w) = (# W32# (word64ToWord# (uncheckedShiftRL64# w 32#)), W32# (word64ToWord# w) #)+#endif
+ Foundation/Primitive/Nat.hs view
@@ -0,0 +1,119 @@+{-# LANGUAGE CPP                       #-}+{-# LANGUAGE KindSignatures            #-}+{-# LANGUAGE DataKinds                 #-}+{-# LANGUAGE GADTs                     #-}+{-# LANGUAGE TypeOperators             #-}+{-# LANGUAGE TypeFamilies              #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE ScopedTypeVariables       #-}+{-# LANGUAGE UndecidableInstances      #-}+#if __GLASGOW_HASKELL__ < 710+# error "IMPORT ERROR: cannot include this file with GHC version below 7.10+#else+#if __GLASGOW_HASKELL__ < 800+{-# LANGUAGE ConstraintKinds           #-}+#endif+module Foundation.Primitive.Nat+    ( Nat+    , KnownNat+    , natVal+    , type (<=), type (<=?), type (+), type (*), type (^), type (-)+    , CmpNat+    -- * Nat convertion+    , natValInt+    , natValInt8+    , natValInt16+    , natValInt32+    , natValInt64+    , natValWord+    , natValWord8+    , natValWord16+    , natValWord32+    , natValWord64+    -- * Maximum bounds+    , NatNumMaxBound+    -- * Constraint+    , NatInBoundOf+    , NatWithinBound+    ) where++#include "MachDeps.h"++import           GHC.TypeLits+import           Foundation.Internal.Base+import           Foundation.Internal.Natural+import           Data.Int (Int8, Int16, Int32, Int64)+import           Data.Word (Word8, Word16, Word32, Word64)+import qualified Prelude (fromIntegral)++#if __GLASGOW_HASKELL__ >= 800+import           Data.Type.Bool+#endif++natValInt :: forall n proxy . (KnownNat n, NatWithinBound Int n) => proxy n -> Int+natValInt n = Prelude.fromIntegral (natVal n)++natValInt64 :: forall n proxy . (KnownNat n, NatWithinBound Int64 n) => proxy n -> Int64+natValInt64 n = Prelude.fromIntegral (natVal n)++natValInt32 :: forall n proxy . (KnownNat n, NatWithinBound Int32 n) => proxy n -> Int32+natValInt32 n = Prelude.fromIntegral (natVal n)++natValInt16 :: forall n proxy . (KnownNat n, NatWithinBound Int16 n) => proxy n -> Int16+natValInt16 n = Prelude.fromIntegral (natVal n)++natValInt8 :: forall n proxy . (KnownNat n, NatWithinBound Int8 n) => proxy n -> Int8+natValInt8 n = Prelude.fromIntegral (natVal n)++natValWord :: forall n proxy . (KnownNat n, NatWithinBound Word n) => proxy n -> Word+natValWord n = Prelude.fromIntegral (natVal n)++natValWord64 :: forall n proxy . (KnownNat n, NatWithinBound Word64 n) => proxy n -> Word64+natValWord64 n = Prelude.fromIntegral (natVal n)++natValWord32 :: forall n proxy . (KnownNat n, NatWithinBound Word32 n) => proxy n -> Word32+natValWord32 n = Prelude.fromIntegral (natVal n)++natValWord16 :: forall n proxy . (KnownNat n, NatWithinBound Word16 n) => proxy n -> Word16+natValWord16 n = Prelude.fromIntegral (natVal n)++natValWord8 :: forall n proxy . (KnownNat n, NatWithinBound Word8 n) => proxy n -> Word8+natValWord8 n = Prelude.fromIntegral (natVal n)++-- | Get Maximum bounds of different Integral / Natural types related to Nat+type family NatNumMaxBound ty where+    NatNumMaxBound Int64  = 0x7fffffffffffffff+    NatNumMaxBound Int32  = 0x7fffffff+    NatNumMaxBound Int16  = 0x7fff+    NatNumMaxBound Int8   = 0x7f+    NatNumMaxBound Word64 = 0xffffffffffffffff+    NatNumMaxBound Word32 = 0xffffffff+    NatNumMaxBound Word16 = 0xffff+    NatNumMaxBound Word8  = 0xff+#if WORD_SIZE_IN_BITS == 64+    NatNumMaxBound Int    = NatNumMaxBound Int64+    NatNumMaxBound Word   = NatNumMaxBound Word64+#else+    NatNumMaxBound Int    = NatNumMaxBound Int32+    NatNumMaxBound Word   = NatNumMaxBound Word32+#endif++-- | Check if a Nat is in bounds of another integral / natural types+type family NatInBoundOf ty n where+    NatInBoundOf Integer n = 'True+    NatInBoundOf Natural n = 'True+    NatInBoundOf ty      n = n <=? NatNumMaxBound ty++-- | Constraint to check if a natural is within a specific bounds of a type.+--+-- i.e. given a Nat `n`, is it possible to convert it to `ty` without losing information+#if __GLASGOW_HASKELL__ >= 800+type family NatWithinBound ty (n :: Nat) where+    NatWithinBound ty n = If (NatInBoundOf ty n)+        (() ~ ())+        (TypeError ('Text "Natural " ':<>: 'ShowType n ':<>: 'Text " is out of bounds for " ':<>: 'ShowType ty))+#else+type NatWithinBound ty n = NatInBoundOf ty n ~ 'True+#endif++#endif
Foundation/Primitive/Types.hs view
@@ -1,4 +1,3 @@--- | -- Module      : Foundation.Primitive.Types -- License     : BSD-style -- Maintainer  : Vincent Hanquez <vincent@snarc.org>@@ -23,8 +22,13 @@     , sizeRecast     , offsetAsSize     , sizeAsOffset+    , primWordGetByteAndShift+    , primWord64GetByteAndShift+    , primWord64GetHiLo     ) where +#include "MachDeps.h"+ import           GHC.Prim import           GHC.Int import           GHC.Types@@ -37,6 +41,10 @@ import           Foundation.Primitive.Monad import qualified Prelude (quot) +#if WORD_SIZE_IN_BITS < 64+import           GHC.IntWord64+#endif+ #ifdef FOUNDATION_BOUNDS_CHECK  divBytes :: PrimType ty => Offset ty -> (Int -> Int)@@ -189,8 +197,49 @@                   -> ty                   -> prim () +sizeInt, sizeWord :: Size Word8+#if WORD_SIZE_IN_BITS == 64+sizeInt = Size 8+sizeWord = Size 8+#else+sizeInt = Size 4+sizeWord = Size 4+#endif+ {-# SPECIALIZE [3] primBaUIndex :: ByteArray# -> Offset Word8 -> Word8 #-} +instance PrimType Int where+    primSizeInBytes _ = sizeInt+    {-# INLINE primSizeInBytes #-}+    primBaUIndex ba (Offset (I# n)) = I# (indexIntArray# ba n)+    {-# INLINE primBaUIndex #-}+    primMbaURead mba (Offset (I# n)) = primitive $ \s1 -> let (# s2, r #) = readIntArray# mba n s1 in (# s2, I# r #)+    {-# INLINE primMbaURead #-}+    primMbaUWrite mba (Offset (I# n)) (I# w) = primitive $ \s1 -> (# writeIntArray# mba n w s1, () #)+    {-# INLINE primMbaUWrite #-}+    primAddrIndex addr (Offset (I# n)) = I# (indexIntOffAddr# addr n)+    {-# INLINE primAddrIndex #-}+    primAddrRead addr (Offset (I# n)) = primitive $ \s1 -> let (# s2, r #) = readIntOffAddr# addr n s1 in (# s2, I# r #)+    {-# INLINE primAddrRead #-}+    primAddrWrite addr (Offset (I# n)) (I# w) = primitive $ \s1 -> (# writeIntOffAddr# addr n w s1, () #)+    {-# INLINE primAddrWrite #-}++instance PrimType Word where+    primSizeInBytes _ = sizeWord+    {-# INLINE primSizeInBytes #-}+    primBaUIndex ba (Offset (I# n)) = W# (indexWordArray# ba n)+    {-# INLINE primBaUIndex #-}+    primMbaURead mba (Offset (I# n)) = primitive $ \s1 -> let (# s2, r #) = readWordArray# mba n s1 in (# s2, W# r #)+    {-# INLINE primMbaURead #-}+    primMbaUWrite mba (Offset (I# n)) (W# w) = primitive $ \s1 -> (# writeWordArray# mba n w s1, () #)+    {-# INLINE primMbaUWrite #-}+    primAddrIndex addr (Offset (I# n)) = W# (indexWordOffAddr# addr n)+    {-# INLINE primAddrIndex #-}+    primAddrRead addr (Offset (I# n)) = primitive $ \s1 -> let (# s2, r #) = readWordOffAddr# addr n s1 in (# s2, W# r #)+    {-# INLINE primAddrRead #-}+    primAddrWrite addr (Offset (I# n)) (W# w) = primitive $ \s1 -> (# writeWordOffAddr# addr n w s1, () #)+    {-# INLINE primAddrWrite #-}+ instance PrimType Word8 where     primSizeInBytes _ = Size 1     {-# INLINE primSizeInBytes #-}@@ -454,3 +503,22 @@ offsetAsSize :: Offset a -> Size a offsetAsSize (Offset a) = Size a {-# INLINE offsetAsSize #-}++primWordGetByteAndShift :: Word# -> (# Word#, Word# #)+primWordGetByteAndShift w = (# and# w 0xff##, uncheckedShiftRL# w 8# #)+{-# INLINE primWordGetByteAndShift #-}++#if WORD_SIZE_IN_BITS == 64+primWord64GetByteAndShift :: Word# -> (# Word#, Word# #)+primWord64GetByteAndShift = primWord64GetByteAndShift++primWord64GetHiLo :: Word# -> (# Word#, Word# #)+primWord64GetHiLo w = (# uncheckedShiftRL# w 32# , and# w 0xffffffff## #)+#else+primWord64GetByteAndShift :: Word64# -> (# Word#, Word64# #)+primWord64GetByteAndShift w = (# and# (word64ToWord# w) 0xff##, uncheckedShiftRL64# w 8# #)++primWord64GetHiLo :: Word64# -> (# Word#, Word# #)+primWord64GetHiLo w = (# word64ToWord# (uncheckedShiftRL64# w 32#), word64ToWord# w #)+#endif+{-# INLINE primWord64GetByteAndShift #-}
Foundation/Random.hs view
@@ -16,10 +16,12 @@ --   abstract a generator. -- {-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE ScopedTypeVariables      #-} module Foundation.Random     ( MonadRandom(..)     , MonadRandomState(..)     , RandomGen(..)+    , getRandomPrimType     , withRandomGenerator     , RNG     , RNGv1@@ -27,6 +29,7 @@  import           Foundation.Internal.Base import           Foundation.Internal.Types+import           Foundation.Internal.Proxy import           Foundation.Primitive.Monad import           Foundation.System.Entropy import           Foundation.Array@@ -37,7 +40,7 @@  -- | A monad constraint that allows to generate random bytes class (Functor m, Applicative m, Monad m) => MonadRandom m where-    getRandomBytes :: Int -> m (UArray Word8)+    getRandomBytes :: Size Word8 -> m (UArray Word8)  instance MonadRandom IO where     getRandomBytes = getEntropy@@ -47,8 +50,14 @@     -- | Initialize a new random generator     randomNew :: MonadRandom m => m gen +    -- | Initialize a new random generator from a binary seed.+    --+    -- If `Nothing` is returned, then the data is not acceptable+    -- for creating a new random generator.+    randomNewFrom :: UArray Word8 -> Maybe gen+     -- | Generate N bytes of randomness from a DRG-    randomGenerate :: Int -> gen -> (UArray Word8, gen)+    randomGenerate :: Size Word8 -> gen -> (UArray Word8, gen)  -- | A simple Monad class very similar to a State Monad -- with the state being a RandomGenerator.@@ -74,6 +83,10 @@ instance RandomGen gen => MonadRandom (MonadRandomState gen) where     getRandomBytes n = MonadRandomState (randomGenerate n) +getRandomPrimType :: forall randomly ty . (PrimType ty, MonadRandom randomly) => randomly ty+getRandomPrimType =+    flip A.index 0 . A.unsafeRecast <$> getRandomBytes (A.primSizeInBytes (Proxy :: Proxy ty))+ -- | Run a pure computation with a Random Generator in the 'MonadRandomState' withRandomGenerator :: RandomGen gen                     => gen@@ -97,19 +110,22 @@  instance RandomGen RNGv1 where     randomNew = RNGv1 <$> getRandomBytes 32+    randomNewFrom bs+        | A.length bs == 32 = Just $ RNGv1 bs+        | otherwise         = Nothing     randomGenerate = rngv1Generate -rngv1KeySize :: Int+rngv1KeySize :: Size Word8 rngv1KeySize = 32 -rngv1Generate :: Int -> RNGv1 -> (UArray Word8, RNGv1)-rngv1Generate n (RNGv1 key) = runST $ do-    dst    <- A.newPinned (Size n)-    newKey <- A.newPinned (Size $ rngv1KeySize)+rngv1Generate :: Size Word8 -> RNGv1 -> (UArray Word8, RNGv1)+rngv1Generate n@(Size x) (RNGv1 key) = runST $ do+    dst    <- A.newPinned n+    newKey <- A.newPinned rngv1KeySize     A.withMutablePtr dst        $ \dstP    ->         A.withMutablePtr newKey $ \newKeyP ->         A.withPtr key           $ \keyP    -> do-            _ <- unsafePrimFromIO $ c_rngv1_generate newKeyP dstP keyP (Prelude.fromIntegral n)+            _ <- unsafePrimFromIO $ c_rngv1_generate newKeyP dstP keyP (Prelude.fromIntegral x)             return ()     (,) <$> A.unsafeFreeze dst         <*> (RNGv1 <$> A.unsafeFreeze newKey)
Foundation/String/UTF8.hs view
@@ -623,7 +623,7 @@ -- splitOn :: (Char -> Bool) -> String -> [String] splitOn predicate s-    | sz == Size 0 = []+    | sz == Size 0 = [mempty]     | otherwise    = loop azero azero   where     !sz = size s@@ -955,11 +955,9 @@ unsnoc :: String -> Maybe (String, Char) unsnoc s     | null s    = Nothing-    | otherwise =-        let (s1,s2) = revSplitAt 1 s-         in case toList s1 of -- TODO use index instead of toList-                [c] -> Just (s2, c)-                _   -> internalError "unsnoc"+    | otherwise = case index s (length s - 1) of+        Nothing -> Nothing+        Just c  -> Just (revDrop 1 s, c)  -- | Extract the First character of a string, and the String stripped of the first character. --@@ -967,11 +965,9 @@ uncons :: String -> Maybe (Char, String) uncons s     | null s    = Nothing-    | otherwise =-        let (s1,s2) = splitAt 1 s-         in case toList s1 of -- TODO use index instead of ToList-                [c] -> Just (c, s2)-                _   -> internalError "uncons"+    | otherwise = case index s 0 of+          Nothing -> Nothing+          Just c  -> Just (c, drop 1 s)  -- | Look for a predicate in the String and return the matched character, if any. find :: (Char -> Bool) -> String -> Maybe Char
+ Foundation/System/Bindings/Network.hsc view
@@ -0,0 +1,45 @@+-- |+-- Module      :  Foundation.System.Bindings.HostName+-- License     :  BSD-style+-- Maintainer  :  Nicolas Di Prima <nicolas@primetype.co.uk>+-- Stability   :  provisional+-- Portability :  portable+--+module Foundation.System.Bindings.Network+    ( -- * error+      getHErrno+    , herr_HostNotFound+    , herr_NoData+    , herr_NoRecovery+    , herr_TryAgain+    ) where++import Foundation.Internal.Base+import Foreign.C.Types++#ifdef mingw32_HOST_OS+# include <winsock2.h>+#else+# include "netinet/in.h"+# include "netdb.h"+#endif++herr_HostNotFound+  , herr_NoData+  , herr_NoRecovery+  , herr_TryAgain+    :: CInt+#ifdef mingw32_HOST_OS+herr_HostNotFound = (#const WSAHOST_NOT_FOUND)+herr_NoData       = (#const WSANO_DATA)+herr_NoRecovery   = (#const WSANO_RECOVERY)+herr_TryAgain     = (#const WSATRY_AGAIN)+#else+herr_HostNotFound = (#const HOST_NOT_FOUND)+herr_NoData       = (#const NO_DATA)+herr_NoRecovery   = (#const NO_RECOVERY)+herr_TryAgain     = (#const TRY_AGAIN)+#endif++foreign import ccall unsafe "foundation_network_get_h_errno"+    getHErrno :: IO CInt
Foundation/System/Bindings/Posix.hsc view
@@ -37,7 +37,6 @@     , sysPosix_EAGAIN     , sysPosix_EALREADY     , sysPosix_EBADF-    , sysPosix_EBADMSG     , sysPosix_EBUSY     , sysPosix_ECANCELED     , sysPosix_ECHILD@@ -64,40 +63,32 @@     , sysPosix_EMFILE     , sysPosix_EMLINK     , sysPosix_EMSGSIZE-    , sysPosix_EMULTIHOP     , sysPosix_ENAMETOOLONG     , sysPosix_ENETDOWN     , sysPosix_ENETRESET     , sysPosix_ENETUNREACH     , sysPosix_ENFILE     , sysPosix_ENOBUFS-    , sysPosix_ENODATA     , sysPosix_ENODEV     , sysPosix_ENOENT     , sysPosix_ENOEXEC     , sysPosix_ENOLCK-    , sysPosix_ENOLINK     , sysPosix_ENOMEM     , sysPosix_ENOMSG     , sysPosix_ENOPROTOOPT     , sysPosix_ENOSPC-    , sysPosix_ENOSR-    , sysPosix_ENOSTR     , sysPosix_ENOSYS     , sysPosix_ENOTCONN     , sysPosix_ENOTDIR     , sysPosix_ENOTEMPTY-    , sysPosix_ENOTRECOVERABLE     , sysPosix_ENOTSOCK     , sysPosix_ENOTSUP     , sysPosix_ENOTTY     , sysPosix_ENXIO     , sysPosix_EOPNOTSUPP     , sysPosix_EOVERFLOW-    , sysPosix_EOWNERDEAD     , sysPosix_EPERM     , sysPosix_EPIPE-    , sysPosix_EPROTO     , sysPosix_EPROTONOSUPPORT     , sysPosix_EPROTOTYPE     , sysPosix_ERANGE@@ -105,7 +96,6 @@     , sysPosix_ESPIPE     , sysPosix_ESRCH     , sysPosix_ESTALE-    , sysPosix_ETIME     , sysPosix_ETIMEDOUT     , sysPosix_ETXTBSY     , sysPosix_EWOULDBLOCK@@ -118,7 +108,6 @@ sysPosix_EAGAIN = (#const EAGAIN) sysPosix_EALREADY = (#const EALREADY) sysPosix_EBADF = (#const EBADF)-sysPosix_EBADMSG = (#const EBADMSG) sysPosix_EBUSY = (#const EBUSY) sysPosix_ECANCELED = (#const ECANCELED) sysPosix_ECHILD = (#const ECHILD)@@ -145,40 +134,32 @@ sysPosix_EMFILE = (#const EMFILE) sysPosix_EMLINK = (#const EMLINK) sysPosix_EMSGSIZE = (#const EMSGSIZE)-sysPosix_EMULTIHOP = (#const EMULTIHOP) sysPosix_ENAMETOOLONG = (#const ENAMETOOLONG) sysPosix_ENETDOWN = (#const ENETDOWN) sysPosix_ENETRESET = (#const ENETRESET) sysPosix_ENETUNREACH = (#const ENETUNREACH) sysPosix_ENFILE = (#const ENFILE) sysPosix_ENOBUFS = (#const ENOBUFS)-sysPosix_ENODATA = (#const ENODATA) sysPosix_ENODEV = (#const ENODEV) sysPosix_ENOENT = (#const ENOENT) sysPosix_ENOEXEC = (#const ENOEXEC) sysPosix_ENOLCK = (#const ENOLCK)-sysPosix_ENOLINK = (#const ENOLINK) sysPosix_ENOMEM = (#const ENOMEM) sysPosix_ENOMSG = (#const ENOMSG) sysPosix_ENOPROTOOPT = (#const ENOPROTOOPT) sysPosix_ENOSPC = (#const ENOSPC)-sysPosix_ENOSR = (#const ENOSR)-sysPosix_ENOSTR = (#const ENOSTR) sysPosix_ENOSYS = (#const ENOSYS) sysPosix_ENOTCONN = (#const ENOTCONN) sysPosix_ENOTDIR = (#const ENOTDIR) sysPosix_ENOTEMPTY = (#const ENOTEMPTY)-sysPosix_ENOTRECOVERABLE = (#const ENOTRECOVERABLE) sysPosix_ENOTSOCK = (#const ENOTSOCK) sysPosix_ENOTSUP = (#const ENOTSUP) sysPosix_ENOTTY = (#const ENOTTY) sysPosix_ENXIO = (#const ENXIO) sysPosix_EOPNOTSUPP = (#const EOPNOTSUPP) sysPosix_EOVERFLOW = (#const EOVERFLOW)-sysPosix_EOWNERDEAD = (#const EOWNERDEAD) sysPosix_EPERM = (#const EPERM) sysPosix_EPIPE = (#const EPIPE)-sysPosix_EPROTO = (#const EPROTO) sysPosix_EPROTONOSUPPORT = (#const EPROTONOSUPPORT) sysPosix_EPROTOTYPE = (#const EPROTOTYPE) sysPosix_ERANGE = (#const ERANGE)@@ -186,12 +167,60 @@ sysPosix_ESPIPE = (#const ESPIPE) sysPosix_ESRCH = (#const ESRCH) sysPosix_ESTALE = (#const ESTALE)-sysPosix_ETIME = (#const ETIME) sysPosix_ETIMEDOUT = (#const ETIMEDOUT) sysPosix_ETXTBSY = (#const ETXTBSY) sysPosix_EWOULDBLOCK = (#const EWOULDBLOCK) sysPosix_EXDEV = (#const EXDEV) +#ifdef ENODATA+sysPosix_ENODATA :: CErrno+sysPosix_ENODATA = (#const ENODATA)+#endif++#ifdef ENOSR+sysPosix_ENOSR :: CErrno+sysPosix_ENOSR = (#const ENOSR)+#endif++#ifdef ENOSTR+sysPosix_ENOSTR :: CErrno+sysPosix_ENOSTR = (#const ENOSTR)+#endif++#ifdef ETIME+sysPosix_ETIME :: CErrno+sysPosix_ETIME = (#const ETIME)+#endif++#ifdef EBADMSG+sysPosix_EBADMSG :: CErrno+sysPosix_EBADMSG = (#const EBADMSG)+#endif++#ifdef EMULTIHOP+sysPosix_EMULTIHOP :: CErrno+sysPosix_EMULTIHOP = (#const EMULTIHOP)+#endif++#ifdef ENOLINK+sysPosix_ENOLINK :: CErrno+sysPosix_ENOLINK = (#const ENOLINK)+#endif++#ifdef ENOTRECOVERABLE+sysPosix_ENOTRECOVERABLE :: CErrno+sysPosix_ENOTRECOVERABLE = (#const ENOTRECOVERABLE)+#endif++#ifdef EOWNERDEAD+sysPosix_EOWNERDEAD :: CErrno+sysPosix_EOWNERDEAD = (#const EOWNERDEAD)+#endif++#ifdef EPROTO+sysPosix_EPROTO :: CErrno+sysPosix_EPROTO = (#const EPROTO)+#endif  sysPosix_O_RDONLY     , sysPosix_O_WRONLY
Foundation/System/Entropy.hs view
@@ -27,10 +27,10 @@ #endif  -- | Get some of the system entropy-getEntropy :: Int -> IO (A.UArray Word8)-getEntropy n = do-    m <- A.newPinned (Size n)-    bracket entropyOpen entropyClose $ \ctx -> A.withMutablePtr m $ loop ctx n+getEntropy :: Size Word8 -> IO (A.UArray Word8)+getEntropy n@(Size x) = do+    m <- A.newPinned n+    bracket entropyOpen entropyClose $ \ctx -> A.withMutablePtr m $ loop ctx x     A.unsafeFreeze m   where     loop :: EntropyCtx -> Int -> Ptr Word8 -> IO ()@@ -39,5 +39,5 @@         let chSz = min entropyMaximumSize i         r <- entropyGather ctx p chSz         if r-            then loop ctx (n-chSz) (p `plusPtr` chSz)+            then loop ctx (i-chSz) (p `plusPtr` chSz)             else throwIO EntropySystemMissing
Foundation/System/Info.hs view
@@ -29,16 +29,9 @@ import qualified Data.Version import           Data.Data import qualified GHC.Conc-import Foundation.String-import Foundation.Internal.Base--#ifdef ARCH_IS_UNKNOWN_ENDIAN-import Foreign.Marshal.Alloc (alloca)-import Foreign.Ptr (castPtr)-import Foreign.Storable (poke, peek)-import Data.Word (Word8, Word32)-import System.IO.Unsafe (unsafePerformIO)-#endif+import           Foundation.Internal.Base+import           Foundation.Primitive.Endianness (Endianness(..), endianness)+import           Foundation.String  data OS     = Windows@@ -54,7 +47,7 @@ -- -- This function uses the `base`'s `System.Info.os` function. ---os :: Either String OS+os :: Either [Char] OS os = case System.Info.os of     "darwin"  -> Right OSX     "mingw32" -> Right Windows@@ -63,7 +56,7 @@     "openbsd" -> Right BSD     "netbsd"  -> Right BSD     "freebsd" -> Right BSD-    str       -> Left $ fromList str+    str       -> Left str  -- | Enumeration of the known GHC supported architecture. --@@ -85,7 +78,7 @@ -- -- This function uses the `base`'s `System.Info.arch` function. ---arch :: Either String Arch+arch :: Either [Char] Arch arch = case System.Info.arch of     "i386"          -> Right I386     "x86_64"        -> Right X86_64@@ -96,7 +89,7 @@     "sparc64"       -> Right Sparc64     "arm"           -> Right ARM     "aarch64"       -> Right ARM64-    str             -> Left $ fromList str+    str             -> Left str  -- | get the compiler name --@@ -108,32 +101,3 @@ -- | returns the number of CPUs the machine has cpus :: IO Int cpus = GHC.Conc.getNumProcessors--data Endianness-    = LittleEndian-    | BigEndian-  deriving (Eq, Show)---- | endianness of the current architecture-endianness :: Endianness-#ifdef ARCH_IS_LITTLE_ENDIAN-endianness = LittleEndian-#elif ARCH_IS_BIG_ENDIAN-endianness = BigEndian-#else--- ! ARCH_IS_UNKNOWN_ENDIAN-endianness = unsafePerformIO $ bytesToEndianness <$> word32ToByte input-  where-    input :: Word32-    input = 0x01020304-{-# NOINLINE endianness #-}--word32ToByte :: Word32 -> IO Word8-word32ToByte word = alloca $ \wordPtr -> do-         poke wordPtr word-         peek (castPtr wordPtr)--bytesToEndianness :: Word8 -> Endianness-bytesToEndianness 1 = BigEndian-bytesToEndianness _ = LittleEndian-#endif
+ Foundation/UUID.hs view
@@ -0,0 +1,85 @@+{-# LANGUAGE UnboxedTuples #-}+module Foundation.UUID+    ( UUID(..)+    , nil+    , fromBinary+    ) where++import           Foundation.Internal.Base+import           Foundation.Class.Storable+import           Foundation.Hashing.Hashable+import           Foundation.Bits+import           Foundation.Primitive+import           Foundation.Primitive.Base16+import           Foundation.Primitive.IntegralConv+import qualified Foundation.Array.Unboxed as UA++data UUID = UUID {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64+    deriving (Eq,Ord,Typeable)+instance Show UUID where+    show = toLString+instance Hashable UUID where+    hashMix (UUID a b) = hashMix a . hashMix b+instance Storable UUID where+    peek p = UUID <$> (fromBE <$> peekOff ptr 0)+                  <*> (fromBE <$> peekOff ptr 1)+      where ptr = castPtr p :: Ptr (BE Word64)+    poke p (UUID a b) = do+        pokeOff ptr 0 (toBE a)+        pokeOff ptr 1 (toBE b)+      where ptr = castPtr p :: Ptr (BE Word64)+instance StorableFixed UUID where+    size      _ = 16+    alignment _ = 8++withComponent :: UUID -> (Word32 -> Word16 -> Word16 -> Word16 -> Word64 -> a) -> a+withComponent (UUID a b) f = f x1 x2 x3 x4 x5+  where+    !x1 = integralDownsize (a .>>. 32)+    !x2 = integralDownsize ((a .>>. 16) .&. 0xffff)+    !x3 = integralDownsize (a .&. 0xffff)+    !x4 = integralDownsize (b .>>. 48)+    !x5 = (b .&. 0x0000ffffffffffff)+{-# INLINE withComponent #-}++toLString :: UUID -> [Char]+toLString uuid = withComponent uuid $ \x1 x2 x3 x4 x5 ->+    hexWord_4 x1 $ addDash $ hexWord_2 x2 $ addDash $ hexWord_2 x3 $ addDash $ hexWord_2 x4 $ addDash $ hexWord64_6 x5 []+  where+    addDash = (:) '-'+    hexWord_2 w l = case hexWord16 w of+                         (c1,c2,c3,c4) -> c1:c2:c3:c4:l+    hexWord_4 w l = case hexWord32 w of+                    (c1,c2,c3,c4,c5,c6,c7,c8) -> c1:c2:c3:c4:c5:c6:c7:c8:l+    hexWord64_6 w l = case word64ToWord32s w of+                        (# wHigh, wLow #) -> hexWord_2 (integralDownsize wHigh) $ hexWord_4 wLow l++nil :: UUID+nil = UUID 0 0++fromBinary :: UA.UArray Word8 -> Maybe UUID+fromBinary ba+    | UA.length ba /= 16 = Nothing+    | otherwise          = Just $ UUID w0 w1+  where+    w0 = (b15 .<<. 56) .|. (b14 .<<. 48) .|. (b13 .<<. 40) .|. (b12 .<<. 32) .|.+         (b11 .<<. 24) .|. (b10 .<<. 16) .|. (b9 .<<. 8)   .|. b8+    w1 = (b7 .<<. 56) .|. (b6 .<<. 48) .|. (b5 .<<. 40) .|. (b4 .<<. 32) .|.+         (b3 .<<. 24) .|. (b2 .<<. 16) .|. (b1 .<<. 8)  .|. b0++    b0  = integralUpsize (UA.unsafeIndex ba 0)+    b1  = integralUpsize (UA.unsafeIndex ba 1)+    b2  = integralUpsize (UA.unsafeIndex ba 2)+    b3  = integralUpsize (UA.unsafeIndex ba 3)+    b4  = integralUpsize (UA.unsafeIndex ba 4)+    b5  = integralUpsize (UA.unsafeIndex ba 5)+    b6  = integralUpsize (UA.unsafeIndex ba 6)+    b7  = integralUpsize (UA.unsafeIndex ba 7)+    b8  = integralUpsize (UA.unsafeIndex ba 8)+    b9  = integralUpsize (UA.unsafeIndex ba 9)+    b10 = integralUpsize (UA.unsafeIndex ba 10)+    b11 = integralUpsize (UA.unsafeIndex ba 11)+    b12 = integralUpsize (UA.unsafeIndex ba 12)+    b13 = integralUpsize (UA.unsafeIndex ba 13)+    b14 = integralUpsize (UA.unsafeIndex ba 14)+    b15 = integralUpsize (UA.unsafeIndex ba 15)
benchs/Sys.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE RebindableSyntax #-} {-# LANGUAGE OverloadedStrings #-} module Sys ( benchSys ) where @@ -16,7 +17,8 @@  instance RandomGen NullRandom where     randomNew        = return NullRandom-    randomGenerate n r = (fromList (Prelude.replicate n 0), r)+    randomNewFrom    = error "no randomNewFrom"+    randomGenerate (Size n) r = (fromList (Prelude.replicate n 0), r)  benchSys =     [ bgroup "Random"@@ -25,11 +27,11 @@         , bench "Entropy-1024" $ whnfIO $ getEntropy 1024         ]     , bgroup "RNGv1"-        [ bench "Entropy-1"    $ benchRandom 1 randomNew (Proxy :: Proxy RNGv1)-        , bench "Entropy-1024"    $ benchRandom 1024 randomNew (Proxy :: Proxy RNGv1)-        , bench "Entropy-1M"    $ benchRandom (1024 * 1024) randomNew (Proxy :: Proxy RNGv1)+        [ bench "Entropy-1"     $ benchRandom 1 randomNew (Proxy :: Proxy RNGv1)+        , bench "Entropy-1024"  $ benchRandom 1024 randomNew (Proxy :: Proxy RNGv1)+        , bench "Entropy-1M"    $ benchRandom (Size (1024 * 1024)) randomNew (Proxy :: Proxy RNGv1)         ]     ] -benchRandom :: RandomGen rng => Int -> MonadRandomState NullRandom rng -> Proxy rng -> Benchmarkable+benchRandom :: RandomGen rng => Size Word8 -> MonadRandomState NullRandom rng -> Proxy rng -> Benchmarkable benchRandom n rNew _ = whnf (fst . randomGenerate n) (fst $ withRandomGenerator NullRandom rNew)
+ cbits/foundation_network.c view
@@ -0,0 +1,17 @@+#include "foundation_system.h"++#if defined(FOUNDATION_SYSTEM_WINDOWS)+# include <winsock2.h>+#else+# include "netdb.h"+#endif+++int foundation_network_get_h_errno(void)+{+#if defined(FOUNDATION_SYSTEM_WINDOWS)+  return WSAGetLastError();+#else+  return h_errno;+#endif+}
foundation.cabal view
@@ -1,5 +1,5 @@ Name:                foundation-Version:             0.0.4+Version:             0.0.5 Synopsis:            Alternative prelude with batteries and no dependencies Description:     A custom prelude with no dependencies apart from base.@@ -30,7 +30,7 @@ Homepage:            https://github.com/haskell-foundation/foundation Bug-Reports:         https://github.com/haskell-foundation/foundation/issues Cabal-Version:       >=1.10-tested-with:         GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.1+tested-with:         GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2 extra-source-files:  README.md                      cbits/*.h @@ -76,10 +76,13 @@                      Foundation.Monad.State                      Foundation.Network.IPv4                      Foundation.Network.IPv6+                     Foundation.Network.HostName                      Foundation.System.Info                      Foundation.Strict                      Foundation.Parser                      Foundation.Random+                     Foundation.Check+                     Foundation.UUID                      Foundation.System.Entropy                      Foundation.System.Bindings   Other-modules:     Foundation.Boot.Builder@@ -98,6 +101,9 @@                      Foundation.Hashing.SipHash                      Foundation.Hashing.Hasher                      Foundation.Hashing.Hashable+                     Foundation.Check.Gen+                     Foundation.Check.Arbitrary+                     Foundation.Check.Property                      Foundation.Collection.Buildable                      Foundation.Collection.List                      Foundation.Collection.Element@@ -110,6 +116,7 @@                      Foundation.Collection.Foldable                      Foundation.Collection.Mutable                      Foundation.Collection.Zippable+                     Foundation.Collection.Mappable                      Foundation.Conduit.Internal                      Foundation.Internal.Base                      Foundation.Internal.ByteSwap@@ -138,6 +145,7 @@                      Foundation.Primitive.Types                      Foundation.Primitive.Monad                      Foundation.Primitive.Utils+                     Foundation.Primitive.IntegralConv                      Foundation.Primitive.FinalPtr                      Foundation.Monad.MonadIO                      Foundation.Monad.Exception@@ -155,9 +163,11 @@                      Foundation.Foreign.MemoryMap.Types                      Foundation.Partial                      Foundation.System.Entropy.Common+                     Foundation.System.Bindings.Network    include-dirs:      cbits   C-sources:         cbits/foundation_random.c+                     cbits/foundation_network.c    if os(windows)     Exposed-modules: Foundation.System.Bindings.Windows@@ -176,6 +186,8 @@    if impl(ghc >= 7.10)     Exposed-modules: Foundation.Tuple.Nth+                     Foundation.List.SList+                     Foundation.Primitive.Nat    Default-Extensions: NoImplicitPrelude                       RebindableSyntax@@ -239,13 +251,28 @@   if impl(ghc >= 8.0)     ghc-options:     -Wno-redundant-constraints +Test-Suite check-foundation+  type:              exitcode-stdio-1.0+  hs-source-dirs:    tests+  Main-is:           Checks.hs+  Other-modules:+  Default-Extensions: NoImplicitPrelude+                      RebindableSyntax+                      OverloadedStrings+  Build-Depends:     base >= 3 && < 5+                   , foundation+  ghc-options:       -Wall -fno-warn-orphans -fno-warn-missing-signatures+  default-language:  Haskell2010+  if impl(ghc >= 8.0)+    ghc-options:     -Wno-redundant-constraints+ Test-Suite doctest   type:              exitcode-stdio-1.0   hs-source-dirs:    tests   default-language:  Haskell2010   Main-is:           DocTest.hs   Build-Depends:     base >= 3 && < 5-                   , doctest >= 0.11+                   , doctest >= 0.9   Default-Extensions: NoImplicitPrelude                       RebindableSyntax   if impl(ghc < 7.6)
+ tests/Checks.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE ScopedTypeVariables #-}+module Main where++import Foundation+import Foundation.Check++testAdditive :: forall a . (Eq a, Additive a, Arbitrary a) => Proxy a -> Test+testAdditive _ = Group "Additive"+    [ Property "eq"             $ azero === (azero :: a)+    , Property "a + azero == a" $ \(v :: a)     -> v + azero === v+    , Property "azero + a == a" $ \(v :: a)     -> azero + v === v+    , Property "a + b == b + a" $ \(v1 :: a) v2 -> v1 + v2 === v2 + v1+    ]++main = defaultMain $ Group "foundation"+    [ Group "Numerical"+        [ Group "Int"+            [ testAdditive (Proxy :: Proxy Int)+            ]+        , Group "Word64"+            [ testAdditive (Proxy :: Proxy Word64)+            ]+{-+        , Group "Natural"+            [ testAdditive (Proxy :: Proxy Natural)+            ]+-}+        ]+    ]
tests/Imports.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE CPP #-} module Imports     ( module X     , testCase@@ -10,19 +11,33 @@     , NonZero(..)     , (===?)     , diffList+    , assertEq+    , assertEq'     ) where  import Foundation import Test.Tasty              as X hiding (testGroup) import Test.Tasty.QuickCheck   as X (Arbitrary(..), Gen, suchThat, Property, (===), (==>)-                                    , Small(..), QuickCheckVerbose(..), QuickCheckTests(..)+                                    , Small(..), QuickCheckTests(..)                                     , forAll, vectorOf, frequency, choose, elements)+#if MIN_VERSION_tasty_quickcheck(0,8,4)+import Test.Tasty.QuickCheck   as X (QuickCheckVerbose(..))+#endif import Test.Tasty.HUnit        as X hiding (testCase, assert, assertFailure) import Test.QuickCheck.Monadic as X  import qualified Test.Tasty            as Y import qualified Test.Tasty.QuickCheck as Y import qualified Test.Tasty.HUnit      as Y++assertEq :: (Eq a, Show a) => a -> a -> Bool+assertEq got expected+    | got == expected = True+    | otherwise       = error ("got: " <> show got <> " expected: " <> show expected)+assertEq' :: (Eq a, Show a) => a -> a -> X.Assertion+assertEq' got expected+    | got == expected = return ()+    | otherwise       = error ("got: " <> show got <> " expected: " <> show expected)  testCase :: String -> X.Assertion -> X.TestTree testCase x f = Y.testCase (toList x) f
tests/Test/Foundation/Collection.hs view
@@ -11,8 +11,7 @@  import qualified Prelude -import Test.Tasty-import Test.Tasty.QuickCheck hiding (getNonEmpty)+import Imports  import Foundation import Foundation.Collection@@ -122,7 +121,7 @@                   , Eq (Element a)                   , Ord a, Ord (Item a)                   )-               => LString+               => String                -> Proxy a                -> Gen (Element a)                -> TestTree@@ -164,10 +163,20 @@     withListAndElement = forAll ((,) <$> generateListOfElement genElement <*> genElement)     withNonEmptyElements f = forAll (generateNonEmptyListOfElement 80 genElement) f +testSplitOn :: ( Sequential a+               , Show a, Show (Element a)+               , Eq (Element a)+               , Eq a, Ord a, Ord (Item a), Show a+               )+              => Proxy a -> (Element a -> Bool) -> a+              -> TestTree+testSplitOn _ predicate col = testCase "splitOn (const True) mempty == [mempty]" $+    assertEq' (splitOn predicate col) [col]+ testSequentialOps :: ( Sequential a                      , Show a, Show (Element a)                      , Eq (Element a)-                     , Ord a, Ord (Item a)+                     , Eq a, Ord a, Ord (Item a), Show a                      )                   => Proxy a                   -> Gen (Element a)@@ -194,6 +203,13 @@     , testProperty "init" $ withNonEmptyElements $ \els -> toList (init $ fromListNonEmptyP proxy els) === init els     , testProperty "splitOn" $ withElements2E $ \(l, ch) ->          fmap toList (splitOn (== ch) (fromListP proxy l)) === splitOn (== ch) l+    , testSplitOn proxy (\_ -> True) mempty+    , testProperty "intercalate c (splitOn (c ==) col) == col" $ withElements2E $ \(c, ch) ->+        intercalate [ch] (splitOn (== ch) c) === c+    , testProperty "intercalate c (splitOn (c ==) (col ++ [c]) == (col ++ [c])" $ withElements2E $ \(c, ch) ->+        intercalate [ch] (splitOn (== ch) $ snoc c ch) === (snoc c ch)+    , testProperty "intercalate c (splitOn (c ==) (col ++ [c,c]) == (col ++ [c,c])" $ withElements2E $ \(c, ch) ->+        intercalate [ch] (splitOn (== ch) $ snoc (snoc c ch) ch) === (snoc (snoc c ch) ch)     , testProperty "intersperse" $ withElements2E $ \(l, c) ->         toList (intersperse c (fromListP proxy l)) === intersperse c l     , testProperty "intercalate" $ withElements2E $ \(l, c) ->
tests/Test/Foundation/Misc.hs view
@@ -1,15 +1,18 @@+{-# LANGUAGE OverloadedStrings #-} module Test.Foundation.Misc     ( testHexadecimal+    , testUUID     ) where  import Foundation import Test.Tasty import Test.Tasty.QuickCheck-import Test.QuickCheck.Monadic  import Foundation.Array.Internal (toHexadecimal) import Test.Foundation.Collection (fromListP, toListP) +import qualified Foundation.UUID as UUID+ hex :: [Word8] -> [Word8] hex = loop   where@@ -23,6 +26,11 @@         (q,r) = x `divMod` 16  testHexadecimal = testGroup "hexadecimal"-    [ testProperty  "UArray(W8)" $ \l -> +    [ testProperty  "UArray(W8)" $ \l ->         toList (toHexadecimal (fromListP (Proxy :: Proxy (UArray Word8)) l)) == hex l+    ]++testUUID = testGroup "UUID"+    [ testProperty "show" $ show (UUID.nil) === "00000000-0000-0000-0000-000000000000"+    , testProperty "show-bin" $ fmap show (UUID.fromBinary (fromList [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])) === Just "100f0e0d-0c0b-0a09-0807-060504030201"     ]
tests/Test/Foundation/Random.hs view
@@ -11,7 +11,7 @@ import Foundation.Collection import Foundation.System.Entropy import Foundation.Random-import Control.Monad+import Control.Monad (unless) import qualified Prelude import qualified Data.List import GHC.ST
tests/Test/Foundation/String.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE NoImplicitPrelude   #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies        #-}+{-# LANGUAGE OverloadedStrings   #-} module Test.Foundation.String     ( testStringRefs     ) where
tests/Tests.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE OverloadedStrings   #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies        #-}+{-# LANGUAGE CPP #-} module Main where  import           Control.Monad@@ -74,11 +75,7 @@ --stringEq :: Eq a => (b -> a) -> (String -> b) -> (LString -> a) -> LUString -> Bool --stringEq back f g s = -assertEq :: (Eq a, Show a) => a -> a -> Bool-assertEq got expected-    | got == expected = True-    | otherwise       = error ("got: " <> show got <> " expected: " <> show expected)-+#if MIN_VERSION_tasty_quickcheck(0,8,4) -- | Set in front of tests to make them verbose qcv :: TestTree -> TestTree qcv = adjustOption (\(QuickCheckVerbose _) -> QuickCheckVerbose True)@@ -90,7 +87,7 @@ -- | Scale the number of tests qcnScale :: Int -> TestTree -> TestTree qcnScale n = adjustOption (\(QuickCheckTests actual) -> QuickCheckTests (actual * n))-+#endif  testCaseFilePath :: [TestTree] testCaseFilePath = Prelude.map (makeTestCases . (\x -> (show x, x)))@@ -325,6 +322,25 @@     , testNetworkIPv4     , testNetworkIPv6     , testHexadecimal+    , testUUID+    , testGroup "Issues"+        [ testGroup "218"+            [ testCase "Foundation Strings" $+                let str1 = "aa9a9\154" :: String+                    str2 = "a9\154" :: String+                    Just x = uncons $ snd $ breakElem '9' str1+                    x1 = breakElem '9' $ snd x+                    x2 = breakElem '9' str2+                 in if assertEq x1 x2 then return () else error "failed..."+            , testCase "Lazy Strings" $+                let str1 = "aa9a9\154" :: [Char]+                    str2 = "a9\154" :: [Char]+                    Just x = uncons $ snd $ breakElem '9' str1+                    x1 = breakElem '9' $ snd x+                    x2 = breakElem '9' str2+                 in if assertEq x1 x2 then return () else error "failed..."+            ]+        ]     ]  testCaseModifiedUTF8 :: [Char] -> String -> Assertion