<div dir="ltr">I'd for some reason assumed that vector's indexM actually combined values for the Unboxed case, but it looks like _it_ should be generalized to Applicative, too.<div><br></div><div>-Edwrd</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Aug 13, 2019 at 10:33 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">Well, the reason I say Applicative is because the only method from<br>
Monad which is used is return, which is the same as pure in<br>
Applicative. I'm preparing for when the "Monad of no return" proposal<br>
gets implemented.<br>
<br>
On Tue, Aug 13, 2019 at 11:29 AM Edward Kmett <<a href="mailto:ekmett@gmail.com" target="_blank">ekmett@gmail.com</a>> wrote:<br>
><br>
> 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.<br>
><br>
> I'm not sure that Applicative is strong enough to give the desired behavior, though.<br>
><br>
> e.g. to write a strict fmap (<$!>) you need Monad.<br>
><br>
> -Edward<br>
><br>
> On Tue, Aug 13, 2019 at 9:24 AM Zemyla <<a href="mailto:zemyla@gmail.com" target="_blank">zemyla@gmail.com</a>> wrote:<br>
>><br>
>> 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>