<div dir="ltr">I'm pretty strongly +1 on this, assuming someone is willing to chase down all the implementation issues, as the current API doesn't really allow for efficient usage.<div><br></div><div>I'm not sure that Applicative is strong enough to give the desired behavior, though.</div><div><br></div><div>e.g. to write a strict fmap (<$!>) you need Monad.<br><br></div><div>-Edward</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Aug 13, 2019 at 9:24 AM Zemyla <<a href="mailto:zemyla@gmail.com">zemyla@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">This is an issue I originally proposed on GHC Trac, but I'm posting it<br>
here because (I think) the Data.Array package is under the purview of<br>
the Libraries committee.<br>
<br>
The vector package has indexM and its cousins so that a user can be<br>
strict in the array without necessarily being strict in the value<br>
retrieved from that array. Arrays don't have that sort of thing,<br>
meaning that anything you do that takes an array will necessarily<br>
leave references to the array unless you force the whole thing, and<br>
that's not only inefficient, it's untenable for general libraries.<br>
<br>
What I'm thinking is that the IArray class should have a function like<br>
<br>
unsafeAtM :: (Array a e, Ix i, Applicative m) => a i e -> Int -> m e<br>
<br>
For compatibility with older code that wouldn't necessarily define<br>
this but would define unsafeAt, we'd have the default implementation<br>
<br>
unsafeAtM a !n = pure (unsafeAt a n)<br>
<br>
Also, you could have unsafeAt defined in terms of unsafeAtM, so the<br>
minimal implementation could require only one of them:<br>
<br>
unsafeAt = (coerce :: (a i e -> Int -> Identity e) -> a i e -> Int -><br>
e) unsafeAtM<br>
<br>
Also, (!?) would be a "safe" indexing tool for arrays, which would<br>
incidentally also force the array without forcing the value inside.<br>
You would have<br>
<br>
(!?) :: (Array a e, Ix i) => a i e -> i -> Maybe e<br>
(!?) a e = case bounds a of<br>
  p@(l, u) -> case inRange p e of<br>
    True -> unsafeAtM arr $ unsafeIndex p e<br>
    False -> Nothing<br>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div>