Updating record when referenced by multiple data structures

后端 未结 7 1281
独厮守ぢ
独厮守ぢ 2020-12-10 06:50

Suppose I have a record, e.g. Person, and I want to be able to look this person up through multiple data structures. Maybe there\'s an index by name, another in

7条回答
  •  孤城傲影
    2020-12-10 07:38

    Haskell tries to encourage you to think about values, not entities. By this, I mean that pure code will in most cases structure things by transforming values from one kind to another, not modifying or updating data shared by many others. Equality/identity of objects is defined entirely by their content, not their location. But let me be more concrete.

    The general solution to "pure mutation" is to create an endomorphism. In your case, if you had a Directory of people you could read a person's data with a function with the signature

    type Name = String
    get :: Name -> Directory -> Person
    

    and modify it with a function

    mod :: Name -> (Person -> Person) -> (Directory -> Directory)
    

    If you have a lot of modification functions f, g, h, i then you can string them together

    mod i . mod h . mod g . mod f
    

    But what's important to realize is that every Directory created in that chain can potentially exist on its own and be updated/read/modified. That's the nature of immutability---data is persistent and we have to manually push our data "through time" as we modify it.


    So how do you propagate changes to other structures? In short... you can't. If you're trying to, you're modeling things in ways that are very hard to do purely.

    Haskell asks you What do you mean by "propagate"? These objects are based on data in the past and we cannot mutate that fact.


    There are definitely limitations to pure, immutable data. Some algorithms cannot translate and are often implemented by recreating "pointer arithmetic" atop a unique name generator and a finite Map. If this is your case, it's better to start introducing impure effects via the ST or IO monads where you can get true memory mutation out of the STRef and IORef container types.

提交回复
热议问题