-- |
-- Module      : Streamly.Internal.Data.Tuple.Strict
-- Copyright   : (c) 2019 Composewell Technologies
--               (c) 2013 Gabriel Gonzalez
-- License     : BSD3
-- Maintainer  : streamly@composewell.com
-- Stability   : experimental
-- Portability : GHC
--
-- | Strict data types to be used as accumulator for strict left folds and
-- scans. For more comprehensive strict data types see
-- https://hackage.haskell.org/package/strict-base-types . The names have been
-- suffixed by a prime so that programmers can easily distinguish the strict
-- versions from the lazy ones.
--
-- One major advantage of strict data structures as accumulators in folds and
-- scans is that it helps the compiler optimize the code much better by
-- unboxing. In a big tight loop the difference could be huge.
--
module Streamly.Internal.Data.Tuple.Strict
    (
      Tuple' (..)
    , Tuple3' (..)
    -- XXX Remove this type, use a fuse annotation in Tuple3' itself or use a
    -- custom type where fuse annotation is needed.
    , Tuple3Fused' (..)
    , Tuple4' (..)
    )
where

import Fusion.Plugin.Types (Fuse(..))

-- | A strict '(,)'
data Tuple' a b = Tuple' !a !b deriving Int -> Tuple' a b -> ShowS
[Tuple' a b] -> ShowS
Tuple' a b -> String
(Int -> Tuple' a b -> ShowS)
-> (Tuple' a b -> String)
-> ([Tuple' a b] -> ShowS)
-> Show (Tuple' a b)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b. (Show a, Show b) => Int -> Tuple' a b -> ShowS
forall a b. (Show a, Show b) => [Tuple' a b] -> ShowS
forall a b. (Show a, Show b) => Tuple' a b -> String
showList :: [Tuple' a b] -> ShowS
$cshowList :: forall a b. (Show a, Show b) => [Tuple' a b] -> ShowS
show :: Tuple' a b -> String
$cshow :: forall a b. (Show a, Show b) => Tuple' a b -> String
showsPrec :: Int -> Tuple' a b -> ShowS
$cshowsPrec :: forall a b. (Show a, Show b) => Int -> Tuple' a b -> ShowS
Show

-- XXX Add TupleFused'

-- | A strict '(,,)'
{-# ANN type Tuple3Fused' Fuse #-}
data Tuple3' a b c = Tuple3' !a !b !c deriving Int -> Tuple3' a b c -> ShowS
[Tuple3' a b c] -> ShowS
Tuple3' a b c -> String
(Int -> Tuple3' a b c -> ShowS)
-> (Tuple3' a b c -> String)
-> ([Tuple3' a b c] -> ShowS)
-> Show (Tuple3' a b c)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b c.
(Show a, Show b, Show c) =>
Int -> Tuple3' a b c -> ShowS
forall a b c. (Show a, Show b, Show c) => [Tuple3' a b c] -> ShowS
forall a b c. (Show a, Show b, Show c) => Tuple3' a b c -> String
showList :: [Tuple3' a b c] -> ShowS
$cshowList :: forall a b c. (Show a, Show b, Show c) => [Tuple3' a b c] -> ShowS
show :: Tuple3' a b c -> String
$cshow :: forall a b c. (Show a, Show b, Show c) => Tuple3' a b c -> String
showsPrec :: Int -> Tuple3' a b c -> ShowS
$cshowsPrec :: forall a b c.
(Show a, Show b, Show c) =>
Int -> Tuple3' a b c -> ShowS
Show

-- | A strict '(,,)'
data Tuple3Fused' a b c = Tuple3Fused' !a !b !c deriving Int -> Tuple3Fused' a b c -> ShowS
[Tuple3Fused' a b c] -> ShowS
Tuple3Fused' a b c -> String
(Int -> Tuple3Fused' a b c -> ShowS)
-> (Tuple3Fused' a b c -> String)
-> ([Tuple3Fused' a b c] -> ShowS)
-> Show (Tuple3Fused' a b c)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b c.
(Show a, Show b, Show c) =>
Int -> Tuple3Fused' a b c -> ShowS
forall a b c.
(Show a, Show b, Show c) =>
[Tuple3Fused' a b c] -> ShowS
forall a b c.
(Show a, Show b, Show c) =>
Tuple3Fused' a b c -> String
showList :: [Tuple3Fused' a b c] -> ShowS
$cshowList :: forall a b c.
(Show a, Show b, Show c) =>
[Tuple3Fused' a b c] -> ShowS
show :: Tuple3Fused' a b c -> String
$cshow :: forall a b c.
(Show a, Show b, Show c) =>
Tuple3Fused' a b c -> String
showsPrec :: Int -> Tuple3Fused' a b c -> ShowS
$cshowsPrec :: forall a b c.
(Show a, Show b, Show c) =>
Int -> Tuple3Fused' a b c -> ShowS
Show

-- | A strict '(,,,)'
data Tuple4' a b c d = Tuple4' !a !b !c !d deriving Int -> Tuple4' a b c d -> ShowS
[Tuple4' a b c d] -> ShowS
Tuple4' a b c d -> String
(Int -> Tuple4' a b c d -> ShowS)
-> (Tuple4' a b c d -> String)
-> ([Tuple4' a b c d] -> ShowS)
-> Show (Tuple4' a b c d)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b c d.
(Show a, Show b, Show c, Show d) =>
Int -> Tuple4' a b c d -> ShowS
forall a b c d.
(Show a, Show b, Show c, Show d) =>
[Tuple4' a b c d] -> ShowS
forall a b c d.
(Show a, Show b, Show c, Show d) =>
Tuple4' a b c d -> String
showList :: [Tuple4' a b c d] -> ShowS
$cshowList :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
[Tuple4' a b c d] -> ShowS
show :: Tuple4' a b c d -> String
$cshow :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
Tuple4' a b c d -> String
showsPrec :: Int -> Tuple4' a b c d -> ShowS
$cshowsPrec :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
Int -> Tuple4' a b c d -> ShowS
Show