236 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			236 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
pub trait Functor[*T]
 | 
						|
    fn <U> map(ftu: fn (t: &*T) -> U) -> Self<U>
 | 
						|
end
 | 
						|
 | 
						|
pub trait Functor[*L -> *R]
 | 
						|
    fn mapLeft(flr: fn (l: &*L) -> *R) -> Self<*L, *R>
 | 
						|
end
 | 
						|
 | 
						|
pub enum Option<T>
 | 
						|
    Some(T),
 | 
						|
    None
 | 
						|
end
 | 
						|
 | 
						|
pub enum Either<L, R>
 | 
						|
    Left(L),
 | 
						|
    Right(R)
 | 
						|
end
 | 
						|
 | 
						|
pub impl Functor[*T] for Option<T>
 | 
						|
    fn <U> map(ftu: fn (t: &*T) -> U) -> Self<U>
 | 
						|
        if self is Some(t) then
 | 
						|
            Some(ftu(t))
 | 
						|
        else
 | 
						|
            None
 | 
						|
        end
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
pub impl Functor[*R] for Either<_, *R>
 | 
						|
    fn <U> map(f: fn (t: &*R) -> U) -> Self<_, U>
 | 
						|
        if self is Right(t) then
 | 
						|
            Right(f(t))
 | 
						|
        else
 | 
						|
            self
 | 
						|
        end
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
pub impl Functor[*L -> *R] for Either<L, R>
 | 
						|
    fn mapLeft(f: fn (l: &*L) -> *R) -> Self<*L, *R>
 | 
						|
        if self is Left(l) then
 | 
						|
            Right(f(l))
 | 
						|
        else
 | 
						|
            self
 | 
						|
        end
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
pub trait Monad[*T]
 | 
						|
    static fn lift(t: *T) -> Self<*T>
 | 
						|
    fn <U> flatMap(f: fn (t: &*T) -> Self<U>) -> Self<U>
 | 
						|
end
 | 
						|
 | 
						|
pub trait Default
 | 
						|
    static fn default() -> Self
 | 
						|
end
 | 
						|
 | 
						|
pub trait Empty[*T]
 | 
						|
    static fn empty() -> Self<*T>
 | 
						|
end
 | 
						|
 | 
						|
pub trait Semigroup[*T]
 | 
						|
    type Other<*T>
 | 
						|
 | 
						|
    fn concat(other: &Other<*T>) -> Self<&*T>
 | 
						|
    cons fn consConcat(other: Other<*T>) -> Self<*T>
 | 
						|
end
 | 
						|
 | 
						|
pub int Iterable<T>
 | 
						|
    fn iter() -> Iterator<T> ref self
 | 
						|
    cons fn consIter() -> ConsIterator<T>
 | 
						|
end
 | 
						|
 | 
						|
pub int Iterator<T>
 | 
						|
    fn next() -> Option<&T ref self>
 | 
						|
end
 | 
						|
 | 
						|
pub int ConsIterator<T>
 | 
						|
    fn next() -> Option<T>
 | 
						|
end
 | 
						|
 | 
						|
pub impl Semigroup[*T] for Iterable<*T>
 | 
						|
    type Other = Iterable<*T>
 | 
						|
 | 
						|
    fn concat(other: &Other<*T>) -> Self<*T>
 | 
						|
        let result: Self<*T> = ArrayList(count())
 | 
						|
        for t in self do
 | 
						|
            result.add(t)
 | 
						|
        end
 | 
						|
        for t in other do
 | 
						|
            result.add(t)
 | 
						|
        end
 | 
						|
        result
 | 
						|
    end
 | 
						|
 | 
						|
    cons fn consConcat(other: Other<*T>) -> Self<*T>
 | 
						|
        let result: Self<*T> = ArrayList(count())
 | 
						|
        for t in self do
 | 
						|
            result.add(t)
 | 
						|
        end
 | 
						|
        for t in other do
 | 
						|
            result.add(t)
 | 
						|
        end
 | 
						|
        result
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
pub int List<T> : Iterable<T>
 | 
						|
    fn add(t: T) -> Void
 | 
						|
end
 | 
						|
 | 
						|
pub impl Functor[*T] for List<*T>
 | 
						|
    fn <U> map(f: (t: &*T) -> U) -> Self<U>
 | 
						|
        let mut result: Self<U> = ArrayList(count())
 | 
						|
        for t in self do
 | 
						|
            result.add(f(t))
 | 
						|
        end
 | 
						|
        result
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
pub impl Empty[*T] for List<*T>
 | 
						|
    static fn empty() -> List<*T> = ArrayList()
 | 
						|
end
 | 
						|
 | 
						|
pub inst Monad[*T] for List<*T>
 | 
						|
    static fn lift(t: *T) -> List<*T>
 | 
						|
        let result: List<*T> = ArrayList()
 | 
						|
        result.add(t)
 | 
						|
        result
 | 
						|
    end
 | 
						|
 | 
						|
    fn <U> flatMap(f: fn (t: &*T) -> List<U>) -> List<U>
 | 
						|
        let result: List<U> = ArrayList(count())
 | 
						|
        for t in self do
 | 
						|
            for u in f(t).consIter() do
 | 
						|
                result.add(u)
 | 
						|
            end
 | 
						|
        end
 | 
						|
        result
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
pub class ArrayList<T> : List<T>
 | 
						|
 | 
						|
    let capacity: USize
 | 
						|
    let mut ts: Array<Option<T>>
 | 
						|
    let count: USize = 0
 | 
						|
 | 
						|
    pub ctor(startCapacity: USize = 10)
 | 
						|
        capacity = startCapacity
 | 
						|
        ts = array(startCapacity, None)
 | 
						|
    end
 | 
						|
 | 
						|
    class ArrayListIterator<T>(owner: &ArrayList<T>) /* ref owner (implied by constructor) */ : Iterator<T>
 | 
						|
        let i: USize = 0
 | 
						|
 | 
						|
        impl fn next() -> Option<&T ref self>
 | 
						|
            if owner.ts[i] is Some(t) then
 | 
						|
                i++
 | 
						|
                Some(t)
 | 
						|
            else
 | 
						|
                None
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    class ConsArrayListIterator<T>(ts: Array<Option<T>>) : ConsIterator<T>
 | 
						|
        let i: USize = 0
 | 
						|
 | 
						|
        impl fn next() -> Option<T>
 | 
						|
            if ts[i] is Some then
 | 
						|
                let wrappedT = mem::take(ts[i], None)
 | 
						|
                i++
 | 
						|
                wrappedT
 | 
						|
            else
 | 
						|
                None
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    impl fn iter() -> Iterator<&T> ref self
 | 
						|
        ArrayListIterator(&self)
 | 
						|
    end
 | 
						|
 | 
						|
    impl cons fn consIter() -> Iterator<T>
 | 
						|
        ConsArrayListIterator(mem::take(ts, arrays::empty()))
 | 
						|
    end
 | 
						|
 | 
						|
    impl fn add(t: T) -> Void
 | 
						|
        ts[count] = Some(t)
 | 
						|
        count++
 | 
						|
        if count == capacity then
 | 
						|
            resize()
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    fn resize() -> Void
 | 
						|
        let oldTs = mem::take(&ts, array(capacity * 2, None))
 | 
						|
        for (i, wrappedT) in oldTs.consIter() do
 | 
						|
            ts[i] = wrappedT
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
end
 | 
						|
 | 
						|
pub mod std::core
 | 
						|
 | 
						|
    pub mod mem
 | 
						|
        pub native fn <T> take(target: &T, replacement: T) -> T
 | 
						|
    end
 | 
						|
 | 
						|
    pub native fn <T> array(capacity: USize, init: fn () -> T) -> Array<T>
 | 
						|
 | 
						|
    pub native fn <T> array(capacity: USize) -> Array<T> where T has Default
 | 
						|
 | 
						|
    pub fn <T> list(...items: Array<T>) -> List<T>
 | 
						|
        let result = ArrayList(items.capacity())
 | 
						|
        for item in items.consIter() do
 | 
						|
            result.add(item)
 | 
						|
        end
 | 
						|
        result
 | 
						|
    end
 | 
						|
 | 
						|
end
 | 
						|
 | 
						|
// Other file
 | 
						|
use std::hkt::{Functor[List], Monad[List]}
 | 
						|
 | 
						|
fn main()
 | 
						|
    let someNums: List<Int> = [1, 2, 3, 4, 5]
 | 
						|
    let plusOnes = someNums.map { it + 1 }
 | 
						|
    println plusOnes // 2, 3, 4, 5, 6
 | 
						|
    let twoOfEach = someNums.flatMap { [it, it] }
 | 
						|
    println twoOfEach // 1, 1, 2, 2, 3, 3, 4, 4, 5, 5
 | 
						|
end |