#include <iostream>
#include <string>
using namespace std;
// NOTE that in contrast to other typeclass-supporting languages,
// concept (= typeclass) implementations
// a) MUST be defined BEFORE the concept is introduced and
// b) do not reference the concept directly, because the association
// is structural, not nominal.
string toTypedJson(int x) {
return "{\"type\": \"int\", \"value\": " + to_string(x) + "}";
}
template <typename T>
concept ToTypedJson = requires (T a) {
{toTypedJson(a)} -> convertible_to<string>;
};
template <ToTypedJson T>
void printAsTypedJson(T x) {
cout << toTypedJson(x) << endl;
}
int main() {
printAsTypedJson(123);
}
// https://doc.rust-lang.org/book/ch10-02-traits.html
trait ToTypedJson {
fn to_typed_json(&self) -> String;
}
impl ToTypedJson for i64 {
fn to_typed_json(&self) -> String {
return format!("{{\"type\": \"int\", \"value\": {}}}", self)
}
}
fn print_as_typed_json(x: impl ToTypedJson) {
println!("{}", x.to_typed_json());
}
fn main() {
print_as_typed_json(123);
}
// https://docs.scala-lang.org/scala3/book/ca-type-classes.html
trait TypedJsonConvertible[A]:
extension (a: A) def toTypedJson: String
given TypedJsonConvertible[Int] with
extension (x: Int) def toTypedJson: String =
s"{\"type\": \"int\", \"value\": ${x}}"
def printAsTypedJson[T: TypedJsonConvertible](x: T): Unit =
println(x.toTypedJson);
printAsTypedJson(123);
class ToTypedJson a where
toTypedJson :: a -> String
instance ToTypedJson Integer where
toTypedJson x =
"{\"type\": \"int\", \"value\": " ++ (show x) ++ "}"
printAsTypedJson :: ToTypedJson a => a -> IO ()
printAsTypedJson x = do
putStrLn (toTypedJson x)
main :: IO ()
main = do
printAsTypedJson (123 :: Integer)
Languages with Type Classes include C++, Rust, Scala, Haskell, Coq, Idris
Languages without Type Classes include JavaScript, C, Python, Java, TypeScript, Kotlin, OCaml
View all concepts with or missing a hasTypeClasses measurement
Read more about Type Classes on the web: 1.