5 ms·
Generalised plusequals
- flebron 5mo agoThe 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 https://hackage.haskell.org/package/lens , tutorial at https://hackage.haskell.org/package/lens-tutorial-1.0.5/docs/Control-Lens-Tutorial.html https://hackage.haskell.org/package/lens-tutorial-1.0.5/docs...).
- leontrolski 5mo agoWhat 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 5mo agoIn 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]
- rokob 5mo agoYeah this looks like lenses at first glance
- hatthew 5mo agoIt 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 5mo agoIt 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).
- deleted 5mo ago[deleted]
- hatthew 5mo agoI think I am misunderstanding the behavior of the alt keyword
- beaumayns 5mo agoq has the concept of amend, which is similar: https://code.kx.com/q4m3/6_Functions/#683-general-form-of-function-application 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.
- RodgerTheGreat 5mo agoIn 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 http://beyondloom.com/tools/trylil.html
- leontrolski 5mo agoThis 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 5mo agoAmending 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)