Sketching higher-kinded types.
This commit is contained in:
		
							parent
							
								
									89b643794c
								
							
						
					
					
						commit
						6489b1f1a3
					
				
							
								
								
									
										112
									
								
								sketching/hkt.dm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								sketching/hkt.dm
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,112 @@
 | 
			
		||||
pub hkt Monoid<T has A> {
 | 
			
		||||
    identity: T
 | 
			
		||||
    fn concat(first_item: A, second_item: A): T
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub hkt Monad<T has A> {
 | 
			
		||||
    fn <B> map(mapper: fn (item: A): B): T<B>
 | 
			
		||||
    fn <B> flat_map(mapper: fn (item: A): T<B>): T<B>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Use this one!
 | 
			
		||||
pub hkt Identity(a: A) {
 | 
			
		||||
    fn identity() = a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub hkt Monoid(a: A) : Identity(a) {
 | 
			
		||||
    fn concat(other: Self) = Self(a + other.a)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub hkt Monad1(a: A) {
 | 
			
		||||
    fn <B> map(mapper: fn (from: A): B) = Self(mapper(a))
 | 
			
		||||
    fn <B> flat_map(mapper: fn (from: A): T<B>) = Self(mapper(b)?)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub hkt Monad2<T has A, B> : Monad2<T> {
 | 
			
		||||
    fn map_right(mapper: fn (right: B): B): T
 | 
			
		||||
    fn flat_map_right(mapper: fn (right: B): T): T
 | 
			
		||||
    fn fold_right(folder: fn (right: B): A): T
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub hkt Reader<T has A...> : Monad<T> {
 | 
			
		||||
    impl fn map(mapper) = Self(mapper(self))
 | 
			
		||||
    impl fn flat_map(mapper) = mapper(self)?
 | 
			
		||||
    fn bind(item: A): Self
 | 
			
		||||
    fn bind_from(item_producer: fn (): A): Self
 | 
			
		||||
    fn bind_from_map(item_mapper: fn (item: A): A): Self
 | 
			
		||||
    fn bind_from_flat_map(item_mapper: fn (item: A): T): Self
 | 
			
		||||
    fn ask(): A
 | 
			
		||||
    fn use(user: fn (item: A): T): Self
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub enum type Option<T> : Monad1 {
 | 
			
		||||
    Some(item: T) {
 | 
			
		||||
        impl fn map(mapper) = Success(mapper(item))
 | 
			
		||||
        impl fn flat_map(mapper) = mapper(item)?
 | 
			
		||||
    },
 | 
			
		||||
    None {
 | 
			
		||||
        impl fn map = self
 | 
			
		||||
        impl fn flat_map = self
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub enum type IO<T, E> : Monad2 {
 | 
			
		||||
    Success(item: T) {
 | 
			
		||||
        impl fn map(mapper) = Success(mapper(item))
 | 
			
		||||
        impl fn flat_map(mapper) = mapper(item)?
 | 
			
		||||
        impl fn map_right(mapper) = self
 | 
			
		||||
        impl fn flat_map_right(mapper) = self
 | 
			
		||||
        impl fn fold_right(folder) = self
 | 
			
		||||
    }.
 | 
			
		||||
    Failure(error: E) {
 | 
			
		||||
        impl fn map(mapper) = self
 | 
			
		||||
        impl fn flat_map(mapper) = self
 | 
			
		||||
        impl fn map_right(mapper) = Failure(mapper(error))
 | 
			
		||||
        impl fn flat_map_right(mapper) = mapper(error)?
 | 
			
		||||
        impl fn fold_right(folder) = Success(folder(error))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// usage in a file interface
 | 
			
		||||
decl pub fn open_file(name: String): FileReader<IO<File, Error>>
 | 
			
		||||
 | 
			
		||||
pub int File {
 | 
			
		||||
    name: String
 | 
			
		||||
    fn read_data(): IO<String, Error>
 | 
			
		||||
    fn close: IO<Void, Error>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub type FileReader : Reader<IO<File, Error>> {
 | 
			
		||||
    fld io: IO<File, Error>
 | 
			
		||||
 | 
			
		||||
    impl fn bind(file) {
 | 
			
		||||
        io = Success(file)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl fn bind_from(producer) {
 | 
			
		||||
        io = Success(producer())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl fn bind_from_map(mapper) {
 | 
			
		||||
        io = Success(mapper(io?))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl fn bind_from_flat_map(flat_mapper) {
 | 
			
		||||
        io = Success(flat_mapper(io?)?)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl fn ask() = io?
 | 
			
		||||
 | 
			
		||||
    impl fn use(user) = {
 | 
			
		||||
        user(io?)
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// some other file
 | 
			
		||||
 | 
			
		||||
open_file('test.txt') // FileReader<IO<File, Error>>
 | 
			
		||||
    .flat_map { f -> f.read_data() } // FileReader<IO<String, Error>>
 | 
			
		||||
    .use { f -> f.close() } // FileReader<IO<String, Error>>
 | 
			
		||||
    .ask()? // String
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user