@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
12{-# LANGUAGE FlexibleInstances #-}
23{-# LANGUAGE MonadComprehensions #-}
34{-# LANGUAGE TypeFamilies #-}
@@ -12,16 +13,33 @@ module Main (main) where
1213import Test.Hspec
1314import qualified GHC.Exts as GHC
1415
15−import Data.Functor.Identity
1616import Streamly
17−import Streamly.List (pattern Cons, pattern Nil)
17+
18+#ifdef USE_STREAMLY_LIST
19+import Data.Functor.Identity
20+import Streamly.List (List(..), pattern Cons, pattern Nil, ZipList(..),
21+ fromZipList, toZipList)
1822import qualified Streamly.Prelude as S
19−import qualified Streamly.List as S
23+#else
24+import Prelude -- to suppress compiler warning
25+
26+type List = []
27+
28+pattern Nil :: [a]
29+pattern Nil <- [] where Nil = []
30+
31+pattern Cons :: a -> [a] -> [a]
32+pattern Cons x xs = x : xs
33+infixr 5 `Cons`
34+
35+{-# COMPLETE Nil, Cons #-}
36+#endif
2037
2138main :: IO ()
2239main = hspec $ do
40+#ifdef USE_STREAMLY_LIST
2341 describe "OverloadedLists for 'SerialT Identity' type" $ do
24− it "overloaded lists" $ do
42+ it "Overloaded lists" $ do
2543 ([1..3] :: SerialT Identity Int) `shouldBe` S.fromList [1..3]
2644 GHC.toList ([1..3] :: SerialT Identity Int) `shouldBe` [1..3]
2745
@@ -41,60 +59,149 @@ main = hspec $ do
4159 [(x,y) | x <- [1..2], y <- [1..2]] `shouldBe`
4260 ([(1,1), (1,2), (2,1), (2,2)] :: SerialT Identity (Int, Int))
4361
62+ it "Foldable (sum)" $ sum (S.fromList [1..3] :: SerialT Identity Int)
63+ `shouldBe` 6
64+
65+ describe "OverloadedStrings for 'SerialT Identity' type" $ do
66+ it "overloaded strings" $ do
67+ ("hello" :: SerialT Identity Char) `shouldBe` S.fromList "hello"
68+#endif
69+
4470 describe "OverloadedLists for List type" $ do
4571 it "overloaded lists" $ do
46− [1..3 :: Int] `shouldBe` S.fromSerial (S.fromList [1..3])
47− GHC.toList ([1..3] :: S.List Int) `shouldBe` [1..3]
72+ ([1..3] :: List Int) `shouldBe` GHC.fromList [1..3]
73+ GHC.toList ([1..3] :: List Int) `shouldBe` [1..3]
4874
49− it "pattern constructor constructs a list" $ do
75+ it "Construct empty list" $ (Nil :: List Int) `shouldBe` []
76+
77+ it "Construct a list" $ do
78+ (Nil :: List Int) `shouldBe` []
5079 ('x' `Cons` Nil) `shouldBe` ['x']
5180 (1 `Cons` [2 :: Int]) `shouldBe` [1,2]
81+ (1 `Cons` 2 `Cons` 3 `Cons` Nil :: List Int) `shouldBe` [1,2,3]
82+
83+ it "pattern matches" $ do
84+ case [] of
85+ Nil -> return ()
86+ _ -> expectationFailure "not reached"
87+
88+ case ['x'] of
89+ Cons 'x' Nil -> return ()
90+ _ -> expectationFailure "not reached"
5291
53− it "pattern match on non-empty list" $
5492 case [1..10 :: Int] of
5593 Cons x xs -> do
5694 x `shouldBe` 1
5795 xs `shouldBe` [2..10]
5896 _ -> expectationFailure "not reached"
5997
98+ case [1..10 :: Int] of
99+ x `Cons` y `Cons` xs -> do
100+ x `shouldBe` 1
101+ y `shouldBe` 2
102+ xs `shouldBe` [3..10]
103+ _ -> expectationFailure "not reached"
104+
60105 it "Show instance" $ do
61− show ([1..3] :: S.List Int) `shouldBe` "fromList [1,2,3]"
106+ show ([1..3] :: List Int) `shouldBe`
107+#ifdef USE_STREAMLY_LIST
108+ "List {toSerial = fromList [1,2,3]}"
109+#else
110+ "[1,2,3]"
111+#endif
62112
63113 it "Read instance" $ do
64− (read "fromList [1,2,3]" :: S.List Int) `shouldBe` [1..3]
114+ (read
115+#ifdef USE_STREAMLY_LIST
116+ "List {toSerial = fromList [1,2,3]}"
117+#else
118+ "[1,2,3]"
119+#endif
120+ :: List Int) `shouldBe` [1..3]
65121
66122 it "Eq instance" $ do
67− ([1,2,3] :: S.List Int) == [1,2,3] `shouldBe` True
123+ ([1,2,3] :: List Int) == [1,2,3] `shouldBe` True
68124
69125 it "Ord instance" $ do
70− ([1,2,3] :: S.List Int) > [1,2,1] `shouldBe` True
126+ ([1,2,3] :: List Int) > [1,2,1] `shouldBe` True
71127
72128 it "Monad comprehension" $ do
73129 [(x,y) | x <- [1..2], y <- [1..2]] `shouldBe`
74− ([(1,1), (1,2), (2,1), (2,2)] :: S.List (Int, Int))
130+ ([(1,1), (1,2), (2,1), (2,2)] :: List (Int, Int))
75131
76− describe "OverloadedStrings for 'SerialT Identity' type" $ do
77− it "overloaded strings" $ do
78− ("hello" :: SerialT Identity Char) `shouldBe` S.fromList "hello"
132+ it "Foldable (sum)" $ sum ([1..3] :: List Int) `shouldBe` 6
79133
80134 describe "OverloadedStrings for List type" $ do
81135 it "overloaded strings" $ do
82− "hello" `shouldBe` S.fromSerial (S.fromList "hello")
136+ ("hello" :: List Char) `shouldBe` GHC.fromList "hello"
83137
84− it "pattern match on empty string" $
138+ it "pattern matches" $ do
85139 case "" of
86140 Nil -> return ()
87141 _ -> expectationFailure "not reached"
88142
89− it "pattern matches on singleton string" $
90143 case "a" of
91144 Cons x Nil -> x `shouldBe` 'a'
92145 _ -> expectationFailure "not reached"
93146
94− it "pattern matches on non-empty string" $
95147 case "hello" <> "world" of
96148 Cons x1 (Cons x2 xs) -> do
97149 x1 `shouldBe` 'h'
98150 x2 `shouldBe` 'e'
99151 xs `shouldBe` "lloworld"
100152 _ -> expectationFailure "not reached"
153+
154+#ifdef USE_STREAMLY_LIST
155+ describe "OverloadedLists for ZipList type" $ do
156+ it "overloaded lists" $ do
157+ ([1..3] :: ZipList Int) `shouldBe` GHC.fromList [1..3]
158+ GHC.toList ([1..3] :: ZipList Int) `shouldBe` [1..3]
159+
160+ it "toZipList" $ do
161+ toZipList (Nil :: List Int) `shouldBe` []
162+ toZipList ('x' `Cons` Nil) `shouldBe` ['x']
163+ toZipList (1 `Cons` [2 :: Int]) `shouldBe` [1,2]
164+ toZipList (1 `Cons` 2 `Cons` 3 `Cons` Nil :: List Int) `shouldBe` [1,2,3]
165+
166+ it "fromZipList" $ do
167+ case fromZipList [] of
168+ Nil -> return ()
169+ _ -> expectationFailure "not reached"
170+
171+ case fromZipList ['x'] of
172+ Cons 'x' Nil -> return ()
173+ _ -> expectationFailure "not reached"
174+
175+ case fromZipList [1..10 :: Int] of
176+ Cons x xs -> do
177+ x `shouldBe` 1
178+ xs `shouldBe` [2..10]
179+ _ -> expectationFailure "not reached"
180+
181+ case fromZipList [1..10 :: Int] of
182+ x `Cons` y `Cons` xs -> do
183+ x `shouldBe` 1
184+ y `shouldBe` 2
185+ xs `shouldBe` [3..10]
186+ _ -> expectationFailure "not reached"
187+
188+ it "Show instance" $ do
189+ show ([1..3] :: ZipList Int) `shouldBe`
190+ "ZipList {toZipSerial = fromList [1,2,3]}"
191+
192+ it "Read instance" $ do
193+ (read "ZipList {toZipSerial = fromList [1,2,3]}" :: ZipList Int)
194+ `shouldBe` [1..3]
195+
196+ it "Eq instance" $ do
197+ ([1,2,3] :: ZipList Int) == [1,2,3] `shouldBe` True
198+
199+ it "Ord instance" $ do
200+ ([1,2,3] :: ZipList Int) > [1,2,1] `shouldBe` True
201+
202+ it "Foldable (sum)" $ sum ([1..3] :: ZipList Int) `shouldBe` 6
203+
204+ it "Applicative Zip" $ do
205+ (,) <$> "abc" <*> [1..3] `shouldBe`
206+ ([('a',1),('b',2),('c',3)] :: ZipList (Char, Int))
207+#endif