Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- Represent pure container. Allow work only with existing keys and only if you know keys.
- Real life examples: any shared storages
- */
- fix Pure = class(Key: Fn, Value: Fn)
- {
- /** class of Key */
- fix Key = Key
- /** class of Value */
- fix Value = Value
- /** -> value by {k} or null if {k} is not in container */
- method fix _get += #(k: Key) -> ?Value { abstract }
- /** allow check {k} in container or not */
- method fix _has += #(k: Key) -> Bool { -> @_get(k) != null }
- /**
- set {v} by existing {k}.
- If {k} doesn't exist - @throws {RangeError}.
- -> is container changed or not
- */
- method _overwrite += #(k: Key, v: Value) -> Bool { abstract }
- /** @wrapper of {@_get} */
- operator fix 'get [x]' += #(k: Key) -> ?Value { -> @_get(k) }
- /** @wrapper of {@_overwrite} */
- operator 'set [x]' += #(k: Key, v: Value) { @_overwrite(k, v) }
- }
- /**
- add {@_each} functionality which allow user to know all keys of container
- that + stadard (@_copy) allows great ability to implemet {@_map}, {@_reduce} etc but you still can not implemet {@_filter} which requires {@_del} or other way
- */
- fix Enumerable = class(Key: Fn, Value: Fn) extends Pure(Key, Value)
- {
- /**
- breakable iterate through all container. breaks when user's {_fn} -> not null. -> return of {_fn}
- @match checks {_fn} semantic {_fn(value, key, container)}
- */
- method fix _each += #(_fn: Fn), match { -> _fn._lazyMatch([@Key, @Value, Enumerable]) } { abstract }
- /** checks if container is empty or not */
- method fix _isEmpty += #() -> Bool { -> !(@_each(#{ -> yes }) || no) }
- /**
- stadard functional map, but w/o 2nd {dest} arg
- -> transformed copy {@} applying {_fn} to each value of {@}
- */
- /*
- method fix _map += #(_fn: Fn, out: Fillable), match { -> _fn._lazyMatch([@Key, @Value, Enumerable]) }
- {
- a._each(#@(v, k){ a._overwrite(k, _fn._lazyCall(v, k, @)) })
- -> a
- }
- */
- /**
- compact container to one value applying {r = _fn(r, v, i, c)} recursivaly
- if initial {r} is null => r = 'first' value
- */
- method fix _reduce += #(_fn: Fn, r: ?Auto), match { -> _fn._lazyMatchArgs([r.Class, @Key, @Value, Enumerable]) }
- {
- if(r == null)
- {
- var isFirst = yes
- @_each(#@(v, k){
- if(isFirst)
- {
- r = v
- isFirst = no
- }
- else
- {
- r = _fn._lazyCall(r, v, k, @)
- }
- })
- }
- else
- {
- @_each(#@(v, k){ r = _fn._lazyCall(r, v, k, @) })
- }
- -> r
- }
- }
- /**
- Represents fillable class which allows you abstract fill container.
- Requires key save semantic of {@_add} method
- Useful for generic {_grep}, may be {_sort} etc
- */
- fix Fillable = class(Key: Fn, Value: Fn)
- {
- /**
- add new {v} to container.
- -> key of added {v}
- */
- method _add += #(v: Value) -> Key { abstract }
- /**
- filter {@}, testing {_filter(v, k, @)} and if yes - add to {dest} container
- if {@} == {dest} @throw {UnsupportedError} because this feature requires {@_del}
- */
- /*
- method fix _grep += #(_fn: Fn, dest: ?&Fillable = @Class()){
- if(@ == dest)
- throw UnsupportedError()
- src._each(#@(v, k){
- if(_fn._lazyCall(v, k, @))
- dest._add(v)
- })
- }*/
- }
- /**
- Add {@_set} and {@_del} with key save semantic i.e. deleting key do not change other keys
- Alsa {@_set} automatically create new keys if key did not exist in container unlike {@_overwrite}'s behavior from {Pure}
- {@_del} allow implemet missed functionality in {Enumerable} as {@_filter} and {@_merge}.
- */
- fix Map = class(Key: Fn, Value: Fn) extends Enumerable(Key, Value)
- {
- /**
- set or create {v} by {k}.
- -> container is changed or not
- */
- method _set += #(k: Key, v: Value) -> Bool { abstract }
- /** @wrapper of {@_set} */
- operator 'set [x]' += #(k: Key, v: Value) { @_set(k, v) }
- /**
- delete {k}
- -> container is changed or not
- */
- method _del += #(k: Key) -> Bool { abstract }
- }
- /**
- Set is just Map Value -> Value i.e. Key = Value but has {Fillable} semantic
- */
- fix Set = class(Value: Fn) extends Map(Value, Value), Fillable(Key, Value)
- {
- /** add {v} to container. -> Key */
- method _add += #(v: Value) -> Value { -> @_set(v, v) }
- }
- fix Iter = class(Container: Fn) {
- fix Container = Container
- fix get container += #() -> Container { abstract }
- fix operator "++x" += #{ abstract }
- fix operator "--x" += #{ abstract }
- fix operator "x < y" += #(y) -> Bool { abstract }
- }
- /**
- keys of container are ordered i.e. there is first key, end key, and you can traverse back and front using {@_prev} and {@_next}
- Traverse is strict i.e. throws RangeError if you try to {@_prev(@begin)} or {@_next(@end)}
- */
- fix Ordered = class(Key: Fn, Value: Fn) extends Enumerable(Key, Value)
- {
- /**
- set {v} by existing {k}.
- If {k} doesn't exist - @throws RangeError.
- -> is container changed or not
- */
- method _set += #(k: Key, v: Value) -> Bool { @_overwrite(k, v) }
- /** first key of container */
- abstract get fix begin += #() -> Key {}
- /** end key of container */
- abstract get fix end += #() -> Key {}
- /**
- get key after({n} times) {k}.
- @throws RangeError if {k == @end}
- */
- abstract fix _next += #(k: Key, n: ?Num = 1) -> Key {}
- /**
- get key before({n} times) {k}.
- @throws RangeError if {k == @begin}
- */
- abstract fix _prev += #(k: Key, n: ?Num = 1) -> Key {}
- method fix _diff += #(k1: Key, k2: Key)
- /**
- ordered keys allows implemet {@_each}
- */
- method fix _each += #(_fn: Fn){
- for(var k = @begin; k != @end; k = @_next(k))
- {
- fix ret = _fn._lazyCall(k, @_get(k), @)
- if(ret != null)
- -> ret
- }
- }
- method _sort = #(_less){
- fix _part = #(b, e){
- if()
- }
- }
- }
- /**
- Allow add/remove last item with key save semantic, Fillable
- */
- fix Stack = class(Key: Fn, Value: Fn) extends Ordered(Key, Value), Fillable(Key, Value)
- {
- /**
- add {v} to end of container
- -> key of {v}
- */
- method _pushBack += #(v: Value) -> Key { abstract }
- /**
- -> and remove last item of container
- -> null if container already empty
- */
- method _popBack += #() -> ?Value { abstract }
- /**
- @wrapper of {@_pushBack} for {Fillable}
- */
- method _add = #(v: Value) -> Key { -> @_pushBack(v) }
- }
- /**
- Allow add/remove first item with key save semantic (which is different from Array)
- */
- fix Deque = class(Key: Fn, Value: Fn) extends Stack(Key, Value)
- {
- /**
- insert {v} at begin of container
- -> key of {v}
- */
- method _pushFront = #(v: Value) -> Key { abstract }
- /**
- -> and remove first item of container
- -> null if container already empty
- */
- method _popFront =+ #() -> ?Value { abstract }
- /**
- rotate deque left
- */
- method _rol =+ #(n: Natural = 1){
- if(@_isEmpty())
- ->
- while(--n >= 0)
- @_pushBack(@_popFront())
- }
- /**
- rotate deque right
- */
- method _ror =+ #(n: Natural = 1){
- if(@_isEmpty())
- ->
- while(--n >= 0)
- @_pushFront(@_popBack())
- }
- }
- /**
- Add ability to delete any item from container with key save semantic
- */
- fix FlatList = class(Key: Fn, Value: Fn) extends Deque(Key, Value)
- {
- /**
- delete value by {k}
- -> yes is {k} was in {@}
- */
- method _del =+ #(k: Key) -> Bool { abstract }
- }
- /**
- Add ability to insert value at not only at front or back with key save semantic
- */
- fix List = class(Key: Fn, Value: Fn) extends FlatList(Key, Value)
- {
- /**
- */
- method _insertBefore =+ #(k: Key, v: Value) -> Key { abstract }
- method _insertAfter =+ #(k: Key, v: Value) -> Key { -> @_insertBefore(@_next(k), v) }
- }
- fix Array = class(Key: Fn, Value: Fn) extends Stack(Key, Value)
- {
- method _insertBefore =+ #(k: Key, v: Value) -> Key { abstract }
- method _del =+ #(k: Key) -> Bool { abstract }
- method _insertAfter =+ #(k: Key, v: Value) -> Key { -> @_insertBefore(@_next(k), v) }
- method _pushFront =+ #(v: Value) -> Key { -> @_insertBefore(@begin, v) }
- method _popFront =+ #() -> ?Value { fix k = @begin, v = @[k]; @_del(k); -> v }
- method _pushBack =+ #(v: Value) -> Key { -> @_insertBefore(@end, v) }
- method _popBack =+ #() -> ?Value { fix k = @_prev(@end), v = @[k]; @_del(k); -> v }
- }
- fix RangeError = class extends Error
- {
- }
Add Comment
Please, Sign In to add comment