-- This module defines what a Monad is and some generic monadic operations --#include "Alfa/List.alfa" --#include "Alfa/Tuples.alfa" Class :: #2 = Type package Monads where open Lists use List, cons, map, foldr open Tuples use Unit, unit Monad (M::Set -> Set) :: Class = sig{unit :: (A::Set) -> A -> M A; bind :: (A::Set) -> (B::Set) -> M A -> (A -> M B) -> M B;} return (A::Set)(M::Set -> Set)(d::Monad M)(a::A) :: M A = d.unit A a (>>=) (A::Set) (B::Set) (M::Set -> Set) (d::Monad M) (m1::M A) (m2::A -> M B) :: M B = d.bind A B m1 m2 (>>) (M::Set -> Set)(A::Set)(B::Set)(d::Monad M)(m1::M A)(m2::M B) :: M B = d.bind A B m1 (\(a::A) -> m2) liftM (A::Set)(B::Set)(M::Set -> Set)(d::Monad M)(f::A -> B)(m::M A) :: M B = (>>=) A B M d m (\(a::A) -> return B M d (f a)) ap (A::Set) (B::Set) (M::Set -> Set) (d::Monad M) (mf::M (A -> B)) (mx::M A) :: M B = (>>=) ((h::A) -> B) B M d mf (\(f::(h::A) -> B) -> liftM A B M d f mx) liftM2 (A::Set) (B::Set) (C::Set) (M::Set -> Set) (d::Monad M) (f::A -> B -> C) (m1::M A) (m2::M B) :: M C = ap B C M d (liftM A ((h::B) -> C) M d f m1) m2 sequence_ (M::Set -> Set)(A::Set)(d::Monad M)(ms::List (M A)) :: M Unit = foldr (M A) (M Unit) ((>>) M A Unit d) (return Unit M d unit) ms sequence (M::Set -> Set)(A::Set)(d::Monad M)(ms::List (M A)) :: M (List A) = foldr (M A) (M (List A)) (liftM2 A (List A) (List A) M d (cons A)) (return (List A) M d Nil@_) ms mapM (A::Set) (B::Set) (M::Set -> Set) (d::Monad M) (f::A -> M B) (ms::List A) :: M (List B) = sequence M B d (map A (M B) f ms) {-# Alfa unfoldgoals off brief on hidetypeannots off wide nd hiding on var ">>" hide 4 infix var "return" hide 3 var ">>=" hide 4 infix var "sequence_" hide 3 var "liftM" hide 4 var "ap" hide 4 infix leftassoc 2 as "<#" var "liftM2" hide 5 var "mapM" hide 4 var "sequence" hide 3 #-}