@classmethod def make_instance(self, cls, pure, ap): pure = pure**(H[(Applicative, "f")] / "a" >> t("f", "a")) ap = ap**(H[(Applicative, "f")] / t("f", H / "a" >> "b") >> t( "f", "a") >> t("f", "b")) build_instance(Applicative, cls, {"pure": pure, "ap": ap}) return @constraint(Applicative(f)) def appAp(fn: f(a >> b), x: f(a)) -> f(b): """ appAp :: Applicative f => f (a -> b) -> f a -> f b """ return Applicative[x].ap(fn, x) @Infix def ap(f, x): """ (ap) :: Applicative f => f (a -> b) -> f a -> f b This is infix and non-curried version of `appAp`. """ return Applicative[x].ap(f, x) instance(Applicative, List).where(pure=lambda x: L[[x]], ap=lambda fs, xs: L[[f(x) for f in fs for x in xs]])
in imperative languages. """ return Monad[m].bind(m, const(k)) @sig(H[(Monad, "m")] / t("m", t("m", "a")) >> t("m", "a")) def join(m): """ join :: Monad m => m (m a) -> m a The join function is the conventional monad join operator. It is used to remove one level of monadic structure, projecting its bound argument into the outer level. """ __id = (lambda x: x)**(H / "a" >> "a") return bind(m, __id) @sig(H[(Monad, "m")] / (H / "a" >> "r") >> t("m", "a") >> t("m", "r")) def liftM(fn, m): """ liftM :: Monad m => (a1 -> r) -> m a1 -> m r Promote a function to a monad. """ return fmap(fn, m) instance(Monad, List).where( bind=lambda x, fn: L[itertools.chain.from_iterable(fmap(fn, x))])
The Either type represents values with two possibilities: a value of type `Either a b` is either `Left a` or `Right b`. The Either type is sometimes used to represent a value which is either correct or an error; by convention, the `Left` constructor is used to hold an error value and the `Right` constructor is used to hold a correct value (mnemonic: “right” also means “correct”). """ Left: a Right: b Left, Right = Either.enums instance(Functor, Either).where(fmap=lambda f, v: ~(caseof(v) | m(Left(m.e)) >> Left(p.e) | m(Right(m.ra)) >> Right(f(p.ra)))) instance(Applicative, Either).where(pure=Right, ap=lambda v, x: ~(caseof(v) | m(Left(m.l)) >> Left(p.l) | m(Right(m.r)) >> fmap(p.r, x))) instance(Monad, Either).where(bind=lambda v, f: ~(caseof(v) | m(Left(m.e)) >> Left(p.e) | m(Right(m.a)) >> f(p.a))) def in_either(fn): """
return not elem(x, t) @constraint(Foldable(r)) def find(f: a >> bool, t: r(a)) -> Maybe(a): """ find :: Foldable r => (a -> bool) -> r a -> Maybe a The find function takes a predicate and a structure and returns the leftmost element of the structure matching the predicate, or Nothing if there is no such element. """ return DL.find(f, toList(t)) #=============================================================================# # Instances instance(Foldable, List).where(foldr=DL.foldr, foldr1=DL.foldr1, foldl=DL.foldl, foldl_=DL.foldl_, foldl1=DL.foldl1, null=DL.null, length=DL.length, elem=DL.elem, minimum=DL.minimum, maximum=DL.maximum, sum=DL.sum, product=DL.product)
@sig(H[(Num, "a")] / "a" >> "a" >> "a") def mul(a, b): """ mul :: Num a => a -> a -> a Multiplies two numbers. """ return Num[a].mul(a, b) instance(Num, int).where(add=int.__add__, mul=int.__mul__, abs=int.__abs__, signum=lambda x: -1 if x < 0 else (1 if x > 0 else 0), fromInteger=int, negate=int.__neg__, sub=int.__sub__) instance(Num, float).where(add=float.__add__, mul=float.__mul__, abs=float.__abs__, signum=lambda x: -1.0 if x < 0.0 else (1.0 if x > 0.0 else 0.0), fromInteger=float, negate=float.__neg__, sub=float.__sub__) instance(Num, complex).where(add=complex.__add__, mul=complex.__mul__,
@annotated def unsafePerformIO(io: IO(a)) -> a: """ unsafePerformIO :: IO a -> a Unsafe performs IO. """ return io.i0(Star) @annotated def unsafeFmapIO(f: a >> b, x: IO(a), n: Unit) -> b: return f(unsafePerformIO(x)) @annotated def unsafeApIO(fn: IO(a >> b), x: IO(a), n: Unit) -> b: return unsafePerformIO(fn)(unsafePerformIO(x)) @annotated def unsafeBindIO(x: IO(a), f: a >> IO(b), n: Unit) -> b: return unsafePerformIO(f(unsafePerformIO(x))) instance(Functor, IO).where(fmap=lambda f, x: LazyPure(unsafeFmapIO(f, x))) instance(Applicative, IO).where(pure=pure, ap=lambda f, x: LazyPure(unsafeApIO(f, x))) instance(Monad, IO).where(bind=lambda x, f: LazyPure(unsafeBindIO(x, f)))
@Infix def map(f, x): """ (map) :: Functor f => (a -> b) -> (f a -> f b) This is infix and non-curried version of `fmap`. Maps function over functor. """ return Functor[x].fmap(f, x) @constraint(Functor(f)) def fmap(fn: a >> b, x: f(a)) -> f(b): """ fmap :: Functor f => (a -> b) -> (f a -> f b) Maps function over functor. """ return Functor[x].fmap(fn, x) @constraint(Functor(f)) def void(x: f(a)) -> f(Unit): return fmap(const(Star), x) instance( Functor, List).where(fmap=lambda fn, lst: L[builtins.map(fn, builtins.iter(lst))]) instance(Functor, TypedFunc).where(fmap=TypedFunc.__mul__)
(represented as ``Just a``), or it is empty (represented as ``Nothing``). Using Maybe is a good way to deal with errors or exceptional cases without resorting to drastic measures such as error. The ``Maybe`` type is also a monad. It is a simple kind of error monad, where all errors are represented by ``Nothing``. A richer error monad can be built using the ``Either`` type. """ Nothing : [] Just : a Nothing, Just = Maybe.enums instance(Functor, Maybe).where( fmap = lambda f, x: ~(caseof(x) | m(Just(m.a)) >> Just(f(p.a)) | m(Nothing) >> Nothing) ) instance(Applicative, Maybe).where( pure = Just, ap = lambda fs, xs: ~(caseof((fs, xs)) | m((Just(m.f), Just(m.x))) >> Just(p.f(p.x)) | m((Nothing, m.x)) >> Nothing) ) instance(Monad, Maybe).where( bind = lambda x, f: ~(caseof(x) | m(Just(m.a)) >> f(p.a) | m(Nothing) >> Nothing) )