module Stdlib.Trait.Functor.Monomorphic;
import Stdlib.Data.Fixity open;
import Stdlib.Data.Unit open;
import Stdlib.Trait.Functor.Polymorphic as Poly;
trait
type Functor (Container Elem : Type) :=
  mk@{
    syntax iterator map {init := 0; range := 1};
    
    map : (Elem -> Elem) -> Container -> Container;
  };
open Functor hiding {mk} public;
fromPolymorphicFunctor
  {F : Type -> Type} {{Poly.Functor F}} {Elem} : Functor (F Elem) Elem :=
  Functor.mk@{
    map := Poly.map;
  };
syntax operator <$> lapp;
<$>
  {Container Elem}
  {{Functor Container Elem}}
  (fun : Elem -> Elem)
  (container : Container)
  : Container := map fun container;
syntax operator $> lapp;
$>
  {Container Elem : Type}
  {{Functor Container Elem}}
  (container : Container)
  (element : Elem)
  : Container := \{_ := element} <$> container;