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 | 
