Settings

Theme

Generalised plusequals

leontrolski.github.io

16 points by leontrolski 2 months ago · 12 comments

Reader

flebron 2 months ago

The website asks what they do in Haskell. The answer is property modification and reading, as well as very powerful traversal constructs, use lenses (https://hackage.haskell.org/package/lens , tutorial at https://hackage.haskell.org/package/lens-tutorial-1.0.5/docs...).

  • leontrolskiOP 2 months ago

    What would be the equivalent to this in Haskell (with or without lens):

        cat = Cat(age=3)
        l = [1, [2, cat], 4]
        alt l[1][1].age.=9
    
    That would give us l equal to:

        [1, [2, Cat(age=9)], 4]
    • tome 2 months ago

      In Haskell this list is not well-typed

          l = [1, [2, cat], 4]
      
      There are a few different ways to cook this up. Here's one:

          {-# LANGUAGE TemplateHaskell #-}
          
          import Control.Lens
          
          data Cat = Cat { _age :: Int }
            deriving Show
          makeLenses ''Cat
          
          data Item
            = I Int
            | L [Item]
            | C Cat
            deriving Show
          
          makePrisms ''Item
          
          cat :: Cat
          cat = Cat 3
          
          l :: [Item]
          l = [I 1, L [I 2, C cat], I 4]
          
          l' :: [Item]
          l' = set (ix 1 . _L . ix 1 . _C . age) 9 l
          
      
          ghci> l'
          [I 1,L [I 2,C (Cat {_age = 9})],I 4]
RodgerTheGreat 2 months ago

In Lil[0], this is how ordinary assignment syntax works. Implicitly defining a dictionary stored in a variable named "cat" with a field "age":

    cat.age:3
    # {"age":3}
Defining "l" as in the example in the article. We need the "list" operator to enlist nested values so that the "," operator doesn't concatenate them into a flat list:

    l:1,(list 2,list cat),4
    # (1,(2,{"age":3}),4)
Updating the "age" field in the nested dictionary. Lil's basic datatypes are immutable, so "l" is rebound to a new list containing a new dictionary, leaving any previous references undisturbed:

    l[1][1].age:9
    # (1,(2,{"age":9}),4)
    cat
    # {"age":3}
There's no special "infix" promotion syntax, so that last example would be:

    l:l,5
    # (1,(2,{"age":9}),4,5)
[0] http://beyondloom.com/tools/trylil.html
  • leontrolskiOP 2 months ago

    This is surprising to me:

      l[1][1].age:9
      # (1,(2,{"age":9}),4)
    
    How come it doesn't return just:

      {"age":9}
    
    Or is there something totally different going on with references here? As in, how is this different to:

      l_inner = l[1][1]
      l_inner.age:9
    • RodgerTheGreat 2 months ago

      Amending a slice would amend only the slice:

          l_inner:l[1][1]
          # {"age":3}
          l_inner.age:9
          # {"age":9}
          l_inner
          # {"age":9}
          l
          # (1,(2,{"age":3}),4)
      
      If an amending expression isn't "rooted" in a variable binding, it also returns the entire new structure:

          (1,(list 2,list ().age:5),4)[1][1].age:99
          # (1,(2,{"age":99}),4)
rokob 2 months ago

Yeah this looks like lenses at first glance

hatthew 2 months ago

It seems like this is proposing syntactic sugar to make mutating and non-mutating operations be on equal footing.

> The more interesting example is reassigning the deeply nested l to make the cat inside older, without mutating the original cat

Isn't that mutating l, though? If you're concerned about mutating cat, shouldn't you be concerned about mutating l?

  • two_handfuls 2 months ago

    It doesn't mutate l exactly, it makes a new list slightly different from the original one and assigns it to l.

    That means if someone has a reference to the original l, they do not see the change (because l is immutable. Both of them).

beaumayns 2 months ago

q has the concept of amend, which is similar: https://code.kx.com/q4m3/6_Functions/#683-general-form-of-fu...

It's quite handy, though the syntax for it is rather clunky compared to the rest of the language in my opinion.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection