New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function Request : Array.update #298

Closed
TheSeamau5 opened this Issue Jul 16, 2015 · 5 comments

Comments

Projects
None yet
5 participants
@TheSeamau5
Contributor

TheSeamau5 commented Jul 16, 2015

The following function would be very valuable and it would be best if the implementation were native:

update: Int -> (a -> a) -> Array a -> Array a 

This function would be analogous to Array.set and would be strictly equivalent to the following implementation using both Array.set and Array.get.

update' n f array = 
  case Array.get n array of 
    Nothing -> 
      array 
    Just x -> 
      Array.set (f x) array

(so, here's a good unit/property-based test for the update function).

The goal of having a native implementation is to avoid getting and setting in two distinct steps. This function would prove invaluable in the update step of the Elm Architecture

update : (action -> state -> state) -> Action action -> State state -> State state 
update updateChild action state = 
  case action of 
    ChildAction index childAction -> 
       { state | children <- Array.update index (updateChild action) state.children }

This would avoid the troublesome need of using functions like indexedMap to do this sort of work, and a native implementation could fuse the setting and the getting step of this operation in a way that isn't possible currently.

@sindikat

This comment has been minimized.

Show comment
Hide comment
@sindikat

sindikat Aug 23, 2015

I support this. Matrix third-party library has update, and Matrix a is just a type alias for Array (Array a). I use Matrix's update in my roguelike game all the time.

sindikat commented Aug 23, 2015

I support this. Matrix third-party library has update, and Matrix a is just a type alias for Array (Array a). I use Matrix's update in my roguelike game all the time.

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Aug 23, 2015

Member

Following these guidelines I am going to close this, but I agree that this function would be very valuable and probably should be built in.

Member

evancz commented Aug 23, 2015

Following these guidelines I am going to close this, but I agree that this function would be very valuable and probably should be built in.

@jinjor

This comment has been minimized.

Show comment
Hide comment
@jinjor

jinjor Jan 11, 2017

Contributor

I was about to make the same issue, but maybe we should consider consistency with Dict.update.

Alternative plan:
update: Int -> (Maybe a -> Maybe a) -> Array a -> Array a

Personally, I want both.

Contributor

jinjor commented Jan 11, 2017

I was about to make the same issue, but maybe we should consider consistency with Dict.update.

Alternative plan:
update: Int -> (Maybe a -> Maybe a) -> Array a -> Array a

Personally, I want both.

@boxofrox

This comment has been minimized.

Show comment
Hide comment
@boxofrox

boxofrox Feb 4, 2017

@jinjor, I think your update signature needs a few more details as to how it should be implemented.

For Dict, the (Maybe a -> Maybe a) argument allows a user to assign a default value if Nothing exists at the index.

For an Array, how would that work if your index is out of bounds?

For example, what does the following produce?

things = Array.initialize 5 identity
--=> Array.fromList [ 0, 1, 2, 3, 4 ]

addOrDefault : Int -> Int -> Maybe Int -> Maybe Int
addOrDefault x default y =
  case y of
    Nothing -> Just default
    Just yy -> Just x + yy

Array.update 25 (addOrDefault 5 0) things
--=> ????
  • Do you have a sparse array? Does iteration skip over indices 5 through 23?
  • Do you have a dense array? What value did you fill in for indices 5 through 23?

The benefit of update : Int -> (a -> a) -> Array a -> Array a is that it's simple, useful, and has practically one implementation. Given your signature has tradeoffs and concerns beyond "change value at this index", it may belong in a separate library.

boxofrox commented Feb 4, 2017

@jinjor, I think your update signature needs a few more details as to how it should be implemented.

For Dict, the (Maybe a -> Maybe a) argument allows a user to assign a default value if Nothing exists at the index.

For an Array, how would that work if your index is out of bounds?

For example, what does the following produce?

things = Array.initialize 5 identity
--=> Array.fromList [ 0, 1, 2, 3, 4 ]

addOrDefault : Int -> Int -> Maybe Int -> Maybe Int
addOrDefault x default y =
  case y of
    Nothing -> Just default
    Just yy -> Just x + yy

Array.update 25 (addOrDefault 5 0) things
--=> ????
  • Do you have a sparse array? Does iteration skip over indices 5 through 23?
  • Do you have a dense array? What value did you fill in for indices 5 through 23?

The benefit of update : Int -> (a -> a) -> Array a -> Array a is that it's simple, useful, and has practically one implementation. Given your signature has tradeoffs and concerns beyond "change value at this index", it may belong in a separate library.

@jinjor

This comment has been minimized.

Show comment
Hide comment
@jinjor

jinjor Feb 5, 2017

Contributor

@boxofrox Ah, that's fair. You are right.

Contributor

jinjor commented Feb 5, 2017

@boxofrox Ah, that's fair. You are right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment