IxMonad
implies Monad
for (EDIT: Exists as LowerIx
with newtype LiftIx m i j a = LiftIx (m a)
)
and `
newtype Same :: (k -> k -> k' -> Type) -> (k -> k' -> Type) where
Same :: p f f a -> Same p f a
// This example shows how higher-kinded types can be emulated in Swift today. | |
// It acheives correct typing at the cost of some boilerplate, manual lifting and an existential representation. | |
// The technique below was directly inspired by the paper Lightweight Higher-Kinded Polymorphism | |
// by Jeremy Yallop and Leo White found at http://ocamllabs.io/higher/lightweight-higher-kinded-polymorphism.pdf | |
/// `ConstructorTag` represents a type constructor. | |
/// `Argument` represents an argument to the type constructor. | |
struct Apply<ConstructorTag, Argument> { | |
/// An existential containing a value of `Constructor<Argument>` | |
/// Where `Constructor` is the type constructor represented by `ConstructorTag` |
module Algebra where | |
import Prelude | |
import Control.Monad.Eff (Eff) | |
import Data.Maybe (Maybe(..)) | |
newtype ConsoleAlg f = ConsoleAlg | |
{ printLn :: String -> f Unit | |
, readLn :: f String |
/* | |
* Concept for emulating higher-kinded types using Flow. Instead of passing | |
* a type that has not been applied to parameters, this pattern passes | |
* a type-level function that will map a parameter type to the desired | |
* higher-kinded type applied to the given parameter. | |
* | |
* @flow | |
*/ | |
// a higher-kinded type is represented indirectly via a type-level function from |
// @flow | |
// type-level dictionary URI -> type constructor | |
export type URI2HKT<U, L, A> = { | |
Identity: Identity<A> | |
// other type constructors here... | |
// Option: Option<A>, | |
// Either: Either<L, A>, | |
// Foo: Foo<U, L, A> | |
} |
import { Monad, Monad1 } from 'fp-ts/lib/Monad' | |
import { HKT, URIS, Type } from 'fp-ts/lib/HKT' | |
import { liftA2 } from 'fp-ts/lib/Apply' | |
import { flatten } from 'fp-ts/lib/Chain' | |
import { Newtype, iso } from 'newtype-ts' | |
// Adapted from https://tech.iheart.com/why-fp-its-the-composition-f585d17b01d3 | |
// | |
// newtypes |
/* | |
Slaying a UI Anti Pattern in ReasonML | |
Based on Kris Jenkins original writing. | |
http://blog.jenkster.com/2016/06/how-elm-slays-a-ui-antipattern.html | |
*/ | |
type remoteData 'e 'a = | |
| NotAsked | |
| Loading | |
| Failure 'e | |
| Success 'a; |
IxMonad
implies Monad
for (EDIT: Exists as LowerIx
with newtype LiftIx m i j a = LiftIx (m a)
)
and `
newtype Same :: (k -> k -> k' -> Type) -> (k -> k' -> Type) where
Same :: p f f a -> Same p f a
import Control.Monad.IO.Class | |
import Control.Monad.Codensity | |
import System.IO | |
managedActions :: Codensity IO () | |
managedActions = do | |
input <- Codensity $ withFile "in.txt" ReadMode | |
output <- Codensity $ withFile "out.txt" WriteMode | |
contents <- liftIO $ hGetContents input |
While thinking about comonads as spaces and Day convolution, I realized an interesting thing. The free applicative functor generated by a comonad f
is also a comonad.
The free applicative can be defined in a few different ways, but I like to define it like this:
data FreeApplicative f a = Pure a | Free (Day f (FreeApplicative f) a)
This is a port of the RemoteData type from Kris Jenkins article „How Elm Slays a UI Antipattern“ to TypeScript with TsMonad. There have been ports to Flow and JavaScript as well.