Skip to content

Instantly share code, notes, and snippets.

@Icelandjack
Last active March 13, 2019 03:51
Show Gist options
  • Save Icelandjack/6b9745d30cc57900b51269942c3cd504 to your computer and use it in GitHub Desktop.
Save Icelandjack/6b9745d30cc57900b51269942c3cd504 to your computer and use it in GitHub Desktop.
Row Types for Type Classes

Type classes in terms of row types

type Semigroup s = { Monoid s with mappend :: s -> s -> s | _ }

type Pointed f = { Applicative f with pure  :: forall a. a -> f a | _ }
type Apply   f = { Applicative f with (<*>) :: forall a b. f (a -> b) -> f a -> f b | _ }
type Bind    m = { Monad       m with (>>=) :: forall a b. m a -> (a -> m b) -> m b | _ }

https://youtu.be/YTaNkWjd-ac?t=3604 Edward wants to split MonadReader and MonadWriter up into algebraic (ask + tell) and non-algebraic.. Edward describes a painful change he's putting off, this on the other hand is fine

type AlgMonadReader r m = { MonadReader r m with ask :: m r | _ }

type AlgMonadWriter w m = { MonadWriter r m with tell :: w -> m () | _ }

Here is a PureScript ticket created by Kmett (purescript/purescript-transformers#63) that proposes this

More info: http://comonad.com/reader/2011/monads-from-comonads/

Sadly this breaks down a little for Writer and Reader as the mtl unfortunately has historically included a bunch of extra baggage in these classes. In particular, in reader, the notion of local isn't always available, blocking some otherwise perfectly good MonadReader instances, and I've chosen not to repeat this mistake in comonad-transformers.

@Icelandjack
Copy link
Author

http://openaccess.city.ac.uk/1141/1/Constructors.pdf

data FoldL b a = FoldL (a -> b -> a) a

Although FoldL is not a functor, it nevertheless has operations similar to unit and mult. These can be described using a type class similar to Monoidal, but without the Functor superclass:

class Zip z where 
  zunit :: z ()
  zmult :: z a -> z b -> z (a, b)

consider removing super classes

@Icelandjack
Copy link
Author

Type Inference for GADTs and Anti-unification

(==) :: forall a. {(==) : a -> a -> Bool}. a -> a -> Bool

@Icelandjack
Copy link
Author

https://twitter.com/nomeata/status/979823045471866881

I believe this could be solved the same way

@Icelandjack
Copy link
Author

Icelandjack commented Apr 11, 2018

This is an interesting idea, several ways of expressing this: what is the relationship between Arbitrary and EquivArbitrary

class EquivArbitrary a where
  arbitraryFrom :: Gen (Gen a)
  default
   arbitraryFrom :: Arbitrary a => Gen (Gen a)
  arbitraryFrom = pure arbitrary

class EquivArbitrary a => Arbitrary a where
  arbitrary :: Gen a
  arbitrary = join arbitraryFrom
class Arbitrary a where
  {-# Minimal arbitrary | arbitraryFrom #-}
  arbitrary :: Gen a
  arbitrary = join arbitraryFrom

  arbitraryFrom :: Gen (Gen a)
  arbitraryFrom = pure arbitrary

@Icelandjack
Copy link
Author

Icelandjack commented Apr 17, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment