Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help with preserving order in HashSet #51

Open
ghost opened this issue Jun 14, 2021 · 6 comments
Open

Help with preserving order in HashSet #51

ghost opened this issue Jun 14, 2021 · 6 comments

Comments

@ghost
Copy link

ghost commented Jun 14, 2021

The HashSet is nice to get equality checks. But when you are using it to display UI elements, vector/array is preferable since order of elements seems to change on each re-render of the application. But vector doesn't have the nice properties of HashSet.

Is there some way to get a LinkedHashSet like functionality (Something like: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-linked-hash-set/)?

@emmanueltouzery
Copy link
Owner

yes for that we'd need a new data structure like LinkedHashSet or TreeSet. It is missing in prelude currently, that's true, and it would be a nice feature to have. Actually TreeSet enforces the same sorting order always, while LinkedHashSet keeps the one you give, so presumably LinkedHashSet would be the most interesting here. I'm not sure how much work would that be, presumably not that little :(

@ghost
Copy link
Author

ghost commented Jun 14, 2021

No worries. Would use some sorting after using toArray() on a HashSet for now. You can focus on easy to implement features first.

@emmanueltouzery
Copy link
Owner

ah, I mean the library is actually relatively in maintenance mode at this point: it works great and the API works for me. but maybe such features can be added. i need to find some time for it. need to find out how linked hashmaps work, decide whether we'd roll our own, or reuse some library...

@ghost
Copy link
Author

ghost commented Jun 15, 2021

okay. Initially when I was starting with prelude-ts, ran into some problems with folding over Vector/HashSet, remember it complaining about something where I believe it should not have. Javascript's reduce was a little more relaxed but still had some limitations. I will try to remember and report what it was here. One pattern that I use to write programs is to have an acumulator that is mutating as structure is being folded, the issue was something realted to that.

@ghost
Copy link
Author

ghost commented Jun 15, 2021

Not sure if there are any Typescript libraries out there that provide 'if' and 'case/guard' expressions, since they are clearly preferable over 'if' and 'switch' statements provided by the javascript. I tried to come up with something and using below. My Typescript knowledge is limited and below functions when used as expressions suffers from types not being narrowed, but it would have been nice if these basic blocks could be provided out of the box.

type X<T> = T | (() => X<T>)

function R<V>(expr: X<V>): V {
    if (typeof expr === 'function') {
        return R((expr as () => X<V>)())
    } else {
        return (expr as V)
    }
}

export function when<T extends string, V>(expression: X<T>, guards: { [key in T]: X<V> }): V {
    const expr = typeof expression === 'function' ? R(expression as () => X<T>) : (expression as T)
    return typeof guards[expr] === 'function' ? R(guards[expr] as () => X<V>) : (guards[expr] as V)
}

export function iff<V>(predicate: X<boolean>, expr1: X<V>, expr2: X<V>): V {
    if (typeof predicate === 'function' ? R(predicate) : predicate) {
        return typeof expr1 === 'function' ? R(expr1 as () => X<V>) : (expr1 as V)
    } else {
        return typeof expr2 === 'function' ? R(expr2 as () => X<V>) : (expr2 as V)
    }
}

X is recursive but did not find its recursive nature useful until now.

@emmanueltouzery
Copy link
Owner

no, I feel such basic control flow statements don't belong in prelude. We have combinators (like combining two options, things like that, a). but basic general-purpose control flow, i don't see it belonging in prelude.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
1 participant