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

Typeclasses #66

Open
b-studios opened this issue Apr 15, 2022 · 3 comments
Open

Typeclasses #66

b-studios opened this issue Apr 15, 2022 · 3 comments
Labels
feature New feature or request

Comments

@b-studios
Copy link
Collaborator

We should consider adding typeclasses or similar to prevent repeating code such as sorting datastructures, etc.

@b-studios b-studios added the feature New feature or request label Apr 15, 2022
@phischu phischu mentioned this issue Oct 11, 2023
@serkm
Copy link
Contributor

serkm commented Nov 4, 2023

This seems to me like a straightforward transformation to codata:

  • class definition -> interface definition
  • instance -> top level object
  • type constraints -> implicit parameters

I guess the tricky part would be inferring the correct instance.

@serkm
Copy link
Contributor

serkm commented Nov 4, 2023

A suggestion for syntax:

class C[A] {
    // function declarations
}

instance C[T] {
    // function definitions
}

// type constraints
def f [A] <C[A]> (a: A) = {...}

@serkm
Copy link
Contributor

serkm commented Nov 4, 2023

Another idea would be to add implicit parameters to Effekt and use regular codata to express type classes:

// implicit parameter of type A
def f () <a: A> = {...}

def main() = {
   f() // passes implicit value iff there is exactly one value of type A in scope
}

jiribenes added a commit that referenced this issue Dec 6, 2023
BREAKING CHANGES:
- mutable/array: renamed:
    - arrayFromValue → fill
    - arrayFromLoop → build
    - arrayFromList → fromList

Changes by module:

[effekt]

_all backends_

- `min(n: Int, m: Int): Int`, no specific tests, upstreamed from LLVM backend
- `max(n: Int, m: Int): Int`, no specific tests, upstreamed from LLVM backend

[immutable/list]

_all backends_

- `foreachIndex[A](l: List[A]) { f: (Int, A) => Unit } : Unit`, no specific tests
- `collect[A, B](l: List[A]) { f : A => Option[B] }: List[B]` with new tests in `examples/pos/list/collect`
- `flatMap[A, B](l: List[A]) { f : A => List[B] }: List[B]` with new tests in `examples/pos/list/flatMap`
- `sum(l: List[Int]): Int` with new tests in `examples/pos/list/sum`

[text/string]

_not in LLVM backend_

- `indexOf(str: String, sub: String): Option[Int]` with new tests in `examples/pos/string/indexOf`; not in the Chez backend
- `lastIndexOf(str: String, sub: String): Option[Int]` with new tests in `examples/pos/string/indexOf`; not in the Chez backend
- `startsWith(str: String, prefix: String): Boolean` and `endsWith(str: String, suffix: String): Boolean`, no specific tests; not in the Chez backend
- `substring(str: String, from: Int, to: Int): String` with new tests in `examples/pos/string/substring`
  - most backends had `substring(str: String, from: Int): String` with many different semantics
  - currently claps `from` and `to` to be between `0` and `str.length`
  - ... and makes sure that if `from >= to`, then the result is `""`
- ANSI escape codes (`ANSI_GREEN`, `ANSI_RED`, `ANSI_RESET`)

[mutable/array]

_only in the JS backend_

- reformatted the whole module to be more consistent with the rest of the codebase
- `foreach[T](arr: Array[T]){ action: T => Unit / Control }: Unit`
- `foreachIndex[T](arr: Array[T]){ action: (Int, T) => Unit / Control }: Unit`
- `sum(list: Array[Int]): Int` with new tests in  `examples/pos/array/sum`
- there's also new big set of tests for going between `Array[T]` and `List[T]` in `examples/pos/array/list_conversion` to prevent problems like in #319
- **BREAKING** renamed: `arrayFromValue→fill`, `arrayFromLoop→build`, `arrayFromList→fromList`

[mutable/map]

_only in the JS backend_

- reformatted the whole module to be more consistent with the rest of the codebase
- added `keys`, `values` which return a JS array from `mutable/array` -- there are no tests for this

[test]

- ported from ML backend to JS and Chez with its tests
- could/should be extracted out to shared stdlib (#309)
- added `assertEqual` -- this could possibly fail on backends without general equality, but it's still very useful to me
  - uses an explicit `show` block argument because of backends that don't have a `show` function for all types (related: #66)

---

This is a combination of 33 commits:

immutable/list: add collect, flatMap, sum
mutable/array: reformat
mutable/array: add foreach and foreachIndex
mutable/array: add sum
text/string: add ANSI escape codes
text/string: add indexOf, lastIndexOf
mutable/array: disable array tests on ML backend
immutable/list: Add foreachIndex, sum, collect, flatMap to ML backend
text/string: add indexOf, lastIndexOf to ML backend
text/string: fix 'indexOf' tests for backends without universal print
text/string: rename 'index_of' tests to 'indexOf' to reflect fn name
immutable/list: try adding foreachIndex, collect, flatMap, sum to Chez backend(s)
text/string: ignore 'indexOf' tests in the Chez backend
immutable/list: fix sum in Chez backend (oops)
text/string: add startsWith, endsWith to JS backend
text/string: use proper parameter name in endsWith in ML backend
text/string: change behaviour of lastIndexOf on ML backend to align with JS native impl
mutable/array: don't run list conversion tests on Chez backend
text/string: add tests for substring
effekt.effekt: add min, max
text/string: attempt to unify 'substring' behaviour across backends
text/string: fix off-by-one error in substring (oops)
mutable/array: ignore 'sum' test on Chez backend(s)
text/string: fix 'substring' failing on last character (oops)
text/string: fix thinko in substring on ML backend
text/string: clarify semantics of substring, add more tests
text/string: add ANSI escape sequences to Chez backend(s)
test: port testing framework from ML backend
immutable/list: try ading foreachIndex, collect, flatMap, sum to LLVM backend
test: pass an explicit 'show' block to 'assertEqual' ML backend
immutable/list: explicitly import immutable/option in 'collect' test
mutable/array: rename: arrayFromValue→fill, arrayFromLoop→build, arrayFromList→fromList
mutable/map: add 'values' and 'keys' to JS-backed map
jiribenes added a commit that referenced this issue Dec 6, 2023
BREAKING CHANGES:
- mutable/array: renamed:
    - arrayFromValue → fill
    - arrayFromLoop → build
    - arrayFromList → fromList

Changes by module:

[effekt]

_all backends_

- `min(n: Int, m: Int): Int`, no specific tests, upstreamed from LLVM backend
- `max(n: Int, m: Int): Int`, no specific tests, upstreamed from LLVM backend

[immutable/list]

_all backends_

- `foreachIndex[A](l: List[A]) { f: (Int, A) => Unit } : Unit`, no specific tests
- `collect[A, B](l: List[A]) { f : A => Option[B] }: List[B]` with new tests in `examples/pos/list/collect`
- `flatMap[A, B](l: List[A]) { f : A => List[B] }: List[B]` with new tests in `examples/pos/list/flatMap`
- `sum(l: List[Int]): Int` with new tests in `examples/pos/list/sum`

[text/string]

_not in LLVM backend_

- `indexOf(str: String, sub: String): Option[Int]` with new tests in `examples/pos/string/indexOf`; not in the Chez backend
- `lastIndexOf(str: String, sub: String): Option[Int]` with new tests in `examples/pos/string/indexOf`; not in the Chez backend
- `startsWith(str: String, prefix: String): Boolean` and `endsWith(str: String, suffix: String): Boolean`, no specific tests; not in the Chez backend
- `substring(str: String, from: Int, to: Int): String` with new tests in `examples/pos/string/substring`
  - most backends had `substring(str: String, from: Int): String` with many different semantics
  - currently claps `from` and `to` to be between `0` and `str.length`
  - ... and makes sure that if `from >= to`, then the result is `""`
- ANSI escape codes (`ANSI_GREEN`, `ANSI_RED`, `ANSI_RESET`)

[mutable/array]

_only in the JS backend_

- reformatted the whole module to be more consistent with the rest of the codebase
- `foreach[T](arr: Array[T]){ action: T => Unit / Control }: Unit`
- `foreachIndex[T](arr: Array[T]){ action: (Int, T) => Unit / Control }: Unit`
- `sum(list: Array[Int]): Int` with new tests in  `examples/pos/array/sum`
- there's also new big set of tests for going between `Array[T]` and `List[T]` in `examples/pos/array/list_conversion` to prevent problems like in #319
- **BREAKING** renamed: `arrayFromValue→fill`, `arrayFromLoop→build`, `arrayFromList→fromList`

[mutable/map]

_only in the JS backend_

- reformatted the whole module to be more consistent with the rest of the codebase
- added `keys`, `values` which return a JS array from `mutable/array` -- there are no tests for this

[test]

- ported from ML backend to JS and Chez with its tests
- could/should be extracted out to shared stdlib (#309)
- added `assertEqual` -- this could possibly fail on backends without general equality, but it's still very useful to me
  - uses an explicit `show` block argument because of backends that don't have a `show` function for all types (related: #66)

---

This is a combination of 33 commits:

immutable/list: add collect, flatMap, sum
mutable/array: reformat
mutable/array: add foreach and foreachIndex
mutable/array: add sum
text/string: add ANSI escape codes
text/string: add indexOf, lastIndexOf
mutable/array: disable array tests on ML backend
immutable/list: Add foreachIndex, sum, collect, flatMap to ML backend
text/string: add indexOf, lastIndexOf to ML backend
text/string: fix 'indexOf' tests for backends without universal print
text/string: rename 'index_of' tests to 'indexOf' to reflect fn name
immutable/list: try adding foreachIndex, collect, flatMap, sum to Chez backend(s)
text/string: ignore 'indexOf' tests in the Chez backend
immutable/list: fix sum in Chez backend (oops)
text/string: add startsWith, endsWith to JS backend
text/string: use proper parameter name in endsWith in ML backend
text/string: change behaviour of lastIndexOf on ML backend to align with JS native impl
mutable/array: don't run list conversion tests on Chez backend
text/string: add tests for substring
effekt.effekt: add min, max
text/string: attempt to unify 'substring' behaviour across backends
text/string: fix off-by-one error in substring (oops)
mutable/array: ignore 'sum' test on Chez backend(s)
text/string: fix 'substring' failing on last character (oops)
text/string: fix thinko in substring on ML backend
text/string: clarify semantics of substring, add more tests
text/string: add ANSI escape sequences to Chez backend(s)
test: port testing framework from ML backend
immutable/list: try ading foreachIndex, collect, flatMap, sum to LLVM backend
test: pass an explicit 'show' block to 'assertEqual' ML backend
immutable/list: explicitly import immutable/option in 'collect' test
mutable/array: rename: arrayFromValue→fill, arrayFromLoop→build, arrayFromList→fromList
mutable/map: add 'values' and 'keys' to JS-backed map
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants