41 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			41 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| pub trait HasTruth
 | |
|     fn isTruthy() -> Boolean
 | |
| 
 | |
|     def fn isFalsy() -> Boolean = !self.truthy
 | |
| end
 | |
| 
 | |
| pub trait Functor[Self<T>]
 | |
|     fn <U> map(f: fn (t: T) -> U) -> Self<U>
 | |
| end
 | |
| 
 | |
| pub trait Lift[Self<T>]
 | |
|     static fn lift(t: T) -> Self<T>
 | |
| end
 | |
| 
 | |
| pub trait Applicative[Self<T>, U, V] : Functor[Self] + Lift[Self] where T is fn (u: U) -> V
 | |
|     fn apply(us: Self<U>) -> Self<V>
 | |
| end
 | |
| 
 | |
| pub trait Monad[Self<T>] : Functor[Self] + Lift[Self]
 | |
|     fn <U> flatMap(f: fn (t: T) -> Self<U>) -> Self<U>
 | |
| end
 | |
| 
 | |
| // Traits as higher-kinded types
 | |
| // - Cannot be used as concrete types, casted, etc.
 | |
| // - Cannot be constructed/instantiated
 | |
| // - Imports are different:
 | |
| //   ```
 | |
| //   use std::core::Option
 | |
| //   use std::trait::Monad[Option<*>] // bring in Monad for all Option<*>
 | |
| //   ```
 | |
| // - Once imported, fns are in scope
 | |
| // - Can also be looked-up 'dictionary' style:
 | |
| //   ```
 | |
| //   use std::trait::HasTruth[Option<Boolean>]
 | |
| //
 | |
| //   fn main()
 | |
| //     let maybeTruthy: Option<Boolean> = someOtherApiCall()
 | |
| //     if HasTruth[maybeTruthy].isTruthy() then
 | |
| //       println "It's truthy."
 | |
| //     end
 | |
| //   ``` | 
