Live data from Hacker News

Generalised plusequals

leontrolski.github.io

11–13 of 13 posts

Re: Generalised plusequals

#11
post #2

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... ).

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]

Re: Generalised plusequals

#12
post #2

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... ).

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]

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]

Re: Generalised plusequals

#13

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 dic…

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

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)
Post reply on HN