Unexpected result from Data.Compact.inCompact?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Unexpected result from Data.Compact.inCompact?

Viktor Dukhovni
I am seeing surprising results from 'inCompact' after 'compact'.
It seems there are additional limitations on what can be compacted,
with 'compact' not throwing a 'CompactionFailed' exception in some
cases, and yet not compacting the value.  Is this expected?  When
the below is compiled and run:

    {-# LANGUAGE OverloadedStrings #-}
    module Main (main) where
   
    import           Data.Compact
    import qualified Data.ByteString.Short as S
    import qualified Data.Map.Strict as M
   
    fib :: [Int]
    fib = 0:1:zipWith (+) fib (tail fib)
    u = if M.lookup 3 m == Just 2 then () else undefined
    f3 = head $ drop 3 fib
    m = M.fromList $ zip [0..9] fib
   
    main :: IO ()
    main = do
        test "explicit ()" ()
        test "computed ()" u
        test "explicit Int" (42 :: Int)
        test "computed Int" f3
        test "empty string" ("" :: String)
        test "non-empty string" ("some string" :: String)
        test "empty short bytestring" S.empty
        test "non-empty short bytestring" (S.toShort "some bytestring")
        test "explict empty map" (M.empty :: M.Map Int Int)
        test "computed fib table" m
      where
        test :: String -> a -> IO ()
        test msg val = do
            putStr (msg ++ ": ")
            c <- compact val
            inCompact c (getCompact c) >>= print

it outputs:

    explicit (): False
    computed (): False
    explicit Int: False
    computed Int: True
    empty string: False
    non-empty string: True
    empty short bytestring: True
    non-empty short bytestring: True
    explict empty map: False
    computed fib table: True

but the documentation promises:

    getCompact :: Compact a -> a #

        Retrieve a direct pointer to the value pointed at by a Compact
        reference. If you have used compactAdd, there may be multiple
        Compact references into the same compact region. Upholds the
        property:

            inCompact c (getCompact c) == True

so when 'compact' does not bottom, I'd expect 'True'.

--
        Viktor.
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected result from Data.Compact.inCompact?

Haskell - Haskell-Cafe mailing list
Viktor Dukhovni wrote:
> I am seeing surprising results from 'inCompact' after 'compact'.
> It seems there are additional limitations on what can be compacted,
> with 'compact' not throwing a 'CompactionFailed' exception in some
> cases, and yet not compacting the value.  Is this expected?

This seems to be a documentation problem. `compact` forces and copies
/most/ of the data, but there are some exceptions:

- data that is already compacted is not copied
  (this does not happen in your example, I think)
- statically allocated data is not copied either.
  This includes nullary constructors like (), [], or
  Data.Map.Internal.Tip (the empty map) as well as many statically
  known values like 42 :: Int

See also shouldCompact(),
  https://github.com/ghc/ghc/blob/master/rts/sm/CNF.c#L615

which is called several times in stg_compactAddWorkerzh,
  https://github.com/ghc/ghc/blob/master/rts/Compact.cmm#L50

Cheers,

Bertram
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.