-- Our use of genericLength in easyList will cause our function to loop -- infinitely if we supply an infinite list. Fix this. -- It is not possible to decide whether a list has been defined as infinite. For -- this, there would have to be some reflection capabilities in the -- language. Only a finite limit on the list max. length can be set and checked. -- I was compiling the code of this chapter by 'cabal build'. There were some -- warnings and errors. I have fixed only the errors. -- -- - in BloomFilter/Hash.hs, a part of the import statement for CSize had to -- be changed from '(CSize)' to '(CSize(..))' to import the data -- constructor, not only the type constructor. -- -- - in BloomFilter.hs in the fromList function, the 'B hash . runSTUArray $' -- had to be changed to 'B hash $ runSTUArray $' for the code to compile. -- For testing, I was loading the code into ghci. For it to be able to find -- symbols from the lookup3.o file, I needed to convert it to a shared library -- -- gcc ./dist-newstyle/build/x86_64-linux/ghc-9.6.7/rwh-bloomfilter-0.1/build/cbits/lookup3.o -shared -o liblookup3.so -- -- and load the shared library on start of ghci -- -- stack ghci --ghci-options "-L$(pwd) -llookup3" import BloomFilter.Easy import BloomFilter.Hash (Hashable, doubleHash) import Data.List (genericLength) import qualified BloomFilter as B -- Helper function for forcing evaluation of the easyList and fixedEasyList -- return value easyListLength l = case l of Left err -> error err Right b -> BloomFilter.Easy.length b -- Short length for more illustrative testing maxLength = 10 fixedEasyList errRate values = if isLongerThan values maxLength then Left $ "List longer than " ++ (show maxLength) ++ " elements" else case suggestSizing (genericLength values) errRate of Left err -> Left err Right (bits,hashes) -> Right filt where filt = B.fromList (doubleHash hashes) bits values isLongerThan values max = isLongerThan' values 0 max where isLongerThan' [] l max = False isLongerThan' (v:vs) l max | (l + 1) > max = True | otherwise = isLongerThan' vs (l + 1) max -- ghci> :l 26_a_1.hs -- [1 of 7] Compiling BloomFilter.Hash ( BloomFilter/Hash.hs, interpreted ) -- ... -- [2 of 7] Compiling BloomFilter.Internal ( BloomFilter/Internal.hs, interpreted ) -- [3 of 7] Compiling BloomFilter.Mutable ( BloomFilter/Mutable.hs, interpreted ) -- [4 of 7] Compiling BloomFilter ( BloomFilter.hs, interpreted ) -- [5 of 7] Compiling BloomFilter.Easy ( BloomFilter/Easy.hs, interpreted ) -- [6 of 7] Compiling Main ( 26_a_1.hs, interpreted ) -- Ok, six modules loaded. -- ghci> l = easyList 0.2 [1..] -- ghci> easyListLength l -- *** Exception: stack overflow -- ghci> l = fixedEasyList 0.2 [1..] -- ghci> easyListLength l -- *** Exception: List longer than 10 elements -- CallStack (from HasCallStack): -- error, called at 26_a_1.hs:40:17 in main:Main -- ghci> l = fixedEasyList 0.2 [1..10] -- ghci> easyListLength l -- 34