Nat = Natural Number
Z = Zero
S = Successor
Functions with Natural Numbers:
Functions with the most general thing I could find that supports comparison operators:
enum Nat {
case Z
indirect case S(Nat)
}
func plus(_ x: Nat, _ y: Nat) -> Nat {
switch (x, y) {
case (.Z, _): return y
case (.S(let k), _): return Nat.S(plus(k, y))
}
}
func sub(_ x: Nat, _ y: Nat) -> Nat {
switch(x, y) {
case(_, .Z): return x
case(.Z, _): return Nat.Z
case(.S(let a), .S(let b)): return sub(a, b)
}
}
func qs <T: Comparable> (_ li: [T]) -> [T] {
switch(li) {
case []:
return []
default:
let x = li[0]
let xs = li.dropFirst(1)
return qs(xs.filter { $0 < x }) + [x] + qs(xs.filter { $0 >= x})
}
}
sealed class Nat
object Z : Nat()
class S(val n: Nat) : Nat()
fun plus(x: Nat, y: Nat): Nat = when(x) {
is Z -> y
is S -> S(plus(x.n, y))
}
fun sub(x: Nat, y: Nat): Nat = when {
y is Z -> x
x is Z -> y
x is S && y is S -> sub(x.n, y.n)
else -> null!!
}
fun <T: Comparable<T>> qs(li: List<T>): List<T> = when (li) {
listOf<T>() -> listOf()
else -> {
val x = li[0]
val xs = li.drop(1)
qs(xs.filter { it < x }) + listOf(x) + qs(xs.filter { it >= x })
}
}
sealed trait Nat
case object Z extends Nat
case class S(n: Nat) extends Nat
def plus: (Nat, Nat) => Nat = {
case (Z, y) => y
case (S(k), y) => S(plus(k, y))
}
def sub: (Nat, Nat) => Nat = {
case (x, Z) => x
case (Z, y) => y
case (S(a), S(b)) => sub(a, b)
}
def qs[T <: Ordered[T]]: List[T] => List[T] = {
case List() => List()
case x :: xs => qs(xs.filter(_ < x)) ++ List(x) ++ qs(xs.filter(_ >= x))
}
type Nat = Z | S of Nat
let rec plus = function
| Z, y -> y
| S k, y -> S (plus (k, y))
let rec sub = function
| x, Z -> x
| Z, y -> Z
| S a, S b -> sub (a, b)
let rec qs = function
| [] -> []
| x :: xs -> qs (List.filter ((<) x) xs) @ [x] @ qs (List.filter ((>=) x) xs)
data Nat = Z | S Nat deriving Show
plus Z y = y
plus (S k) y = S (plus k y)
sub x Z = x
sub Z y = Z
sub (S a) (S b) = sub a b
qs [] = []
qs (x:xs) = qs (filter (<x) xs) ++ [x] ++ qs (filter (>=x) xs)
The only language that lacked structural pattern matching.
The only language with non-expression control statements.
The only language lacking null safety, which implicitly makes patterns more prone to error (although the idiom of Scala is Option, null only exists for Java interop).
Can't think of a negative specific to only Haskell in regards to pattern matching, scroll below for negatives it shares with other languages
Mix between Kotlin & Swift // Found out later the Scala version is better than this lol
fun plus(n1: Nat, n2: Nat) = when(n1, n2) {
(Z, _) -> n2
(S(val k), _) -> S(plus(k, n2))
}
println(plus(S(Z), S(S(Z))))
Have to put all code in an object that extends App and run
println(plus(S(Z), S(S(Z))))
print $ plus (S Z) (S (S Z))
print(plus(Nat.S(Nat.Z), Nat.S(Nat.S(Nat.Z))))