nicuveo

Friendly neighbourhood queer nerd.


fullmoon
@fullmoon

… and i've read a lot of fucking haskell code lol

Okay, so check out this Haskell module:

The whole repository is interesting, but I want to draw attention to the following two lines of code from the above module:

instance Foldable (Either a)

This first line is not very surprising. That looks like an ordinary Foldable instance for Either a, just like the one we already have in base

instance Foldable Either

Okay, this second line is absolutely wild. Apparently this module defines a poly-kinded Foldable class and WHAT DOES IT EVEN MEAN TO HAVE A FOLDABLE INSTANCE FOR EITHER BY ITSELF?

So let's check out the Foldable instance provided by this module to get a better understanding of what is going on:

class Functor f => Foldable (f :: i -> j) where
  foldMap :: Monoid (m :: j) => (am) ~> (f am)

… and it just goes downhill from there. This is, like, Haskell necronomicon shit that will inflict untold psychic damage on you if you keep digging into it. And there is a whole repository full of this sort of stuff.


nicuveo
@nicuveo

This is what non-Haskellers think all Haskell code is like, i'm pretty sure! :D

But, wow, yeah, this looks... well, honestly, it looks fun? In a terrifying way, in a "do not make your colleagues review and maintain this unless they're somehow all as incredibly proficient as you" kind of way, in a "i know so terrifyingly little" kind of way.

...i want to play with this now.


You must log in to comment.

in reply to @fullmoon's post:

lens was what taught me about stuff like Endo and Identity and Const and i was like yoooooooooooooo and then i tumbled down the recursion-schemes rabbit hole later which is when i started like really feeling what the deal with functors and foldables was

also machines was my intro to finite automata and algebra was my intro to abstract algebra this is how i started learning those topics in highschool, genuinely

wow, i didn't know that was possible!

So when you pass in Either "raw" for the Foldable instance, how does it treat the Either? Like the type constructor?

My haskell understanding is severly limited, so this looks like magic. Can you explain what is going here?

Like, what does it mean to have a Monoid "m::j" and j is the return type of the function the Foldable is operating on?

Do I read that correctly, that this says "the foldable is operating on some function that returns some value" and "the thing in that monoid must be of the type that is the return type of the function"?

Sooo, the foldmap can now take a type constructing function? is this so you can foldmap over a list of types? what?

Don't worry, it looks like magic to everyone else as well. ^^

So apparently, that there is a synonym for Power, which, um

infixr 0 ⋔
type (⋔) = Power

class (Category ((~>) :: i -> i -> *), hom ~ Hom) => Powered (hom :: j -> j -> i) where
  type Power :: i -> j -> j
  flipped :: forall (a :: j) (u :: i) (b :: j) (a' :: j) (u' :: i) (b' :: j).
    Iso (hom a (Power u b)) (hom a' (Power u' b')) (u `Hom` hom a b) (u' `Hom` hom a' b')

Judging from the instances, I think that Power constructor is roughly some kind of fancy function-like thing?

(~>) is... whatever this means

-- a boring unenriched Hom
type (~>) = (Hom :: i -> i -> *)

Hom here is a type family with instances for (->) and Nat (i.e. natural transformations. Nat f g = forall a. f a ~> g a)

So I guess this foldMap takes a very fancy generalization of (a -> m) and turns it into a very fancy generalization of (f a -> m). In other words, it's really "just" a generalization of the standard foldMap :: Monoid m => (a -> m) -> f a -> m that can be extended to a natural transformation over types with a type parameter (among other things probably)