/*
 * Verrückte Turing-Maschinen — A turing complete game
 * Copyright (C) 2016-2018 kcf <vidofnir@folksprak.org>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

namespace lib_errormonade
	{
		
		/**
		 * @author kcf <vidofnir@folksprak.org>
		 */
		export type type_errormonade<type_value> = lib_call.type_complex<any>;
		
		
		/**
		 * @author kcf <vidofnir@folksprak.org>
		 */
		export function create_nothing<type_value>
			(
			)
			: type_errormonade<type_value>
			{
				return (
					lib_call.wrap<any>
						(
							"nothing",
							{
							}
						)
				);
			}
		
			
		/**
		 * @author kcf <vidofnir@folksprak.org>
		 */
		export function create_just<type_value>
			(
				value : type_value
			)
			: type_errormonade<type_value>
			{
				return (
					lib_call.wrap<any>
						(
							"just",
							{
								"value": value
							}
						)
				);
			}
		
		
		/**
		 * @author kcf <vidofnir@folksprak.org>
		 */
		export function filled<type_value>
			(
				errormonade : type_errormonade<type_value>
			)
			: boolean
			{
				return (
					lib_call.distinguish<any>
						(
							errormonade,
							{
								"nothing": ({}) => false,
								"just": ({"value": value}) => true,
							}
						)
				);
			}
		
		
		/**
		 * @author kcf <vidofnir@folksprak.org>
		 */
		export function read<type_value>
			(
				errormonade : type_errormonade<type_value>
			)
			: type_value
			{
				return (
					lib_call.distinguish<any>
						(
							errormonade,
							{
								"nothing": ({}) => {throw (new Error("read von nothing"));},
								"just": ({"value": value}) => value,
							}
						)
				);
			}
		
		
		/**
		 * @author kcf <vidofnir@folksprak.org>
		 */
		export function propagate<type_value1, type_value2>
			(
				errormonade : type_errormonade<type_value1>,
				funktion : (value1 : type_value1)=>type_errormonade<type_value2>
			)
			: type_errormonade<type_value2>
			{
				return (
					lib_call.distinguish<any>
						(
							errormonade,
							{
								"nothing": ({}) => create_nothing<type_value2>(),
								"just": ({"value": value1}) => funktion(value1),
							}
						)
				);
			}
		
	}

