`th-deepstrict`: enforcing deep strictness of datatypes using TH

th-deepstrict is a library for enforcing (at compile time) that datatypes are deep strict. Deep strictness allows us to guarantee that evaluating a structure evaluates all thunks in all subparts of the structure. This gives us strong guarantees that a type cannot cause a space leak through excessive laziness.

Take a look at the announcement post for more details:

11 Likes

From the Existing tools section:

So whatā€™s the difference between (being) ā€œdeep-strictā€ and hyperstrict?

Indeed those definitions look to be equivalent though hyperstrict has a different meaning in the context of GHCā€™s demand analysis

1 Like

Using ghc demand analysis hyperstrict as a search term finds this (draft) article: Theory and Practice of Demand Analysis in Haskell (2017) - from section 6.3 on page 21 of 34:

The sentence:

evaluation of d is guaranteed to diverge

would be correct where:

  • d = f x
  • f is a hyperstrict function
  • and āŠ„ is a sub-expression of x

So is there another place or article I should be looking at?

No thatā€™s right thatā€™s the sense that is used in GHCā€™s demand analysis.

My understanding is that the sense here of a hyperstrict function is one like:

foo _ = undefined

where we are guaranteed to diverge. Rather than one where we evaluate an argument to normal form.

In any case this is somewhat unrelated to th-deepstrict

Some time ago I suggested adding a primitive hyperstrict-evaluator function to Haskell:

compel :: a -> a

So when I first saw your announcement, I immediately wondered ā€œis that suggestion now redundant?ā€ (perhaps along with deepseq et al ), hence the questions.

That makes sense!
I think such a thing would still be helpful, but you can get something similar with this library.
If you use assertDeepStrict on a type and then force it to WHNF then you will end up with something in NF. Of course thereā€™s still types that canā€™t be deepstrict/hyperstrict, so thereā€™s still a use case for things like deepseq/compel

I love this idea. Thanks for writing the library and the explanation! I hope it will appear on Hackage soon.

1 Like

This is now released on Hackage: th-deepstrict: Check that datatypes are deep strict using Template Haskell.

2 Likes

Great to see this available to all. Sadly it doesnā€™t work with strict-wrapper due to ā€œThe majority of data/type families are currently not supportedā€.

{-# LANGUAGE TemplateHaskell #-}

import Language.Haskell.TH.DeepStrict
import Data.Strict.Wrapper

$(assertDeepStrict =<< [t| Strict ((), ()) |])
1 Like

Thanks for trying it out! I didnā€™t have a good reason to add proper support for type families before. Iā€™ll give it a go now.

1 Like

@tomjaguarpaw Iā€™ve uploaded a version to Hackage that should (:crossed_fingers:) support data/type families. Let me know if you run into any issues.

3 Likes

Wow, thatā€™s great, thanks! This now works as expected:

{-# LANGUAGE TemplateHaskell #-}

import Language.Haskell.TH.DeepStrict
import Data.Strict.Wrapper

$(assertDeepStrict =<< [t| Strict (Strict (Maybe ()), ()) |])
-- Fine


$(assertDeepStrict =<< [t| Strict (Maybe (), ()) |])
-- Error

:slight_smile:

2 Likes