Skip to content

Instantly share code, notes, and snippets.

@masaeedu
Last active August 28, 2018 15:33
Show Gist options
  • Select an option

  • Save masaeedu/55104e6c087dc42b49e11e5bb93066f0 to your computer and use it in GitHub Desktop.

Select an option

Save masaeedu/55104e6c087dc42b49e11e5bb93066f0 to your computer and use it in GitHub Desktop.
What I want from a typechecker
// :: type Eq e = { eq: e -> e -> Bool }
// :: type Semigroup s = { append: s -> s -> s }
// :: type Monoid m =
// :: (Semigroup m)
// :: & { empty: m }
// :: type Functor f = { map: (a -> b) -> (f a -> f b) }
// :: type Apply f =
// :: (Functor f)
// :: & (
// :: { ap: f (a -> b) -> f a -> f b }
// :: | { lift2: (a -> b -> c) -> f a -> f b -> f c }
// :: )
// :: type Applicative f =
// :: (Apply f)
// :: & { pure: a -> f a }
// :: type Bind m =
// :: (Apply m)
// :: & { bind: (a -> m b) -> m a -> m b }
// :: type Monad m =
// :: (Applicative m)
// :: & (Bind m)
// :: type Foldable f =
// :: { foldMap: Monoid m -> (a -> m) -> f a -> m }
// :: | { foldr: (a -> b -> b) -> b -> f a -> b }
// :: | { foldl: (b -> a -> b) -> b -> f a -> b }
// :: type Traversable t =
// :: (Functor t)
// :: & (Foldable t)
// :: & (
// :: { traverse: Applicative f -> (a -> f b) -> t a -> f (t b) }
// :: | { sequence: Applicative f -> t (f a) -> f (t a) }
// :: )
// :: type Semigroupoid s =
// :: { compose: s b c -> s a b -> s a c }
// :: type Category c =
// :: (Semigroupoid c)
// :: & { id: c a a }
// :: (Category (->))
const Fn = (() => {
// :: x -> x
const id = x => x
// :: (b -> c) -> (a -> b) -> (a -> c)
const compose = f => g => x => f(g(x))
// :: x -> y -> x
const _const = x => _ => x
return { id, compose, const: _const }
})()
// :: type Identity a = a
// :: Applicative Identity
const Identity = {
// :: (a -> b) -> (Identity a -> Identity b)
map: Fn.id,
// :: a -> Identity a
pure: Fn.id,
// :: (a -> b -> c) -> (Identity a -> Identity b -> Identity c)
lift2: Fn.id
}
// :: type Const x a = x
// :: Functor (Const x)
// :: & { Applicative: Monoid m -> Applicative (Const m) }
const Const = (() => {
// :: (a -> b) -> (Const x a -> Const x b)
const map = Fn.const(Fn.id)
// :: Monoid m -> Applicative (Const m)
const Applicative = M => ({
map: Const.map,
// :: a -> Const m a
pure: Fn.const(M.empty),
// :: (a -> b -> c) -> Const m a -> Const m b -> Const m c
lift2: Fn.const(M.append)
})
return { map, Applicative }
})()
// :: type Boolean = true | false
// :: { And: Monoid Boolean }
// :: & { Or: Monoid Boolean }
const Bool = {
And: {
empty: true,
append: x => y => x && y
},
Or: {
empty: false,
append: x => y => x || y
}
}
// :: ({ Eq: Eq a -> Eq [a] })
// :: & (Monoid [a])
// :: & (Monad [])
// :: & { Zip: Applicative [] }
// :: & (Traversable [])
// :: & (Monoid [a])
const Arr = (() => {
// Eq
// :: Eq a -> Eq [a]
const Eq = E => ({
eq: Arr.zipWith(E.eq) :> Arr.fold()
})
// Monad
// :: a -> [a]
const pure = x => [x]
// :: (a -> [b]) -> [a] -> [b]
const bind = f => arr => arr.reduce(, [])
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment