0

I have an ST extractor foo :: (forall s . ST s a) -> b for some concrete a and b. Could I safely make another function fooC :: (forall s . ST s (a, c)) -> (b, c), which would allow me to return some additional value out of the ST computation? Can there be a generic transformation addC :: ((forall s . ST s a) -> b) -> (forall s1 . ST s1 (a,c)) -> (b,c) which would be safe to use?

max630
  • 8,762
  • 3
  • 30
  • 55
  • It should be noted that not any `ST` extractor can be matched by signature `(forall s . ST s a) -> b`. For example [`runSTUArray :: (forall s. ST s (STUArray s i e)) -> UArray i e`](https://www.stackage.org/haddock/lts-10.4/array-0.5.2.0/Data-Array-ST.html#v:runSTUArray) does not match it, because `a` is a complex type which has `s` in its parameters. Applying the requested `addC` to it would not typecheck with error "type variable ā€˜s’ would escape its scope" – max630 Mar 20 '18 at 09:59

1 Answers1

3

I'm not really sure I understand what you're trying to accomplish, but this has the right type:

addC :: ((forall s . ST s a) -> b)
     -> (forall s1 . ST s1 (a,c)) -> (b,c)
addC f m = runST $ (\(a,c) -> (f (pure a), c)) <$> m

Note that (forall s. ST s a) is isomorphic to a (as witnessed by pure and runST), so maybe you should just take a function a -> b and a value (a, c).

dfeuer
  • 48,079
  • 5
  • 63
  • 167
  • it was ispired by https://stackoverflow.com/q/49350572/2303202 Thanks. It's unexpected appoach, I need to think more about it. – max630 Mar 19 '18 at 06:02