Please quote the text that is incorrect:
Reimplement Array.map, Array.find, and the ForM instance using for ... in ... loops in the identity monad and compare the resulting code.
In what way is this incorrect?
The ForM instance should use the for … in … syntax in the m monad rather than in the identity monad. Trying to do it in the identity monad is weird and AFAICT requires doing something like storing all of the monadic actions in a List and then consuming the list. Also just trying to write a ForM instance using for … in … is a bit weird to begin with, if I don't want to rely on the fact that Array already has one then I have to iterate over indices. So the identity monad version I ended up with the following:
instance [Monad m] : ForM m (Array α) α where
forM arr f := Id.run do
let mut xs := []
for h : i in [0:arr.size] do
xs := f arr[i] :: xs
pure (xs.foldr (·*>·) (pure ()))
But if I drop the requirement that this be done in the identity monad then I get this much simpler version (once again still trying to avoid relying on the preexisting ForM impl):
instance [Monad m] : ForM m (Array α) α where
forM arr f := do
for h : i in [0:arr.size] do
f arr[i]
Please quote the text that is incorrect:
In what way is this incorrect?
The
ForMinstance should use the for … in … syntax in themmonad rather than in the identity monad. Trying to do it in the identity monad is weird and AFAICT requires doing something like storing all of the monadic actions in aListand then consuming the list. Also just trying to write aForMinstance using for … in … is a bit weird to begin with, if I don't want to rely on the fact thatArrayalready has one then I have to iterate over indices. So the identity monad version I ended up with the following:But if I drop the requirement that this be done in the identity monad then I get this much simpler version (once again still trying to avoid relying on the preexisting
ForMimpl):