newtype BlockF a = Block (V.Vector a) deriving (Eq, Show, Foldable, Traversable, Functor, Monoid)
type Block = BlockF Transaction
type Blockchain = Cofree MerkleF Block
Does anyone really think this is how one should write software? I think that constructions like Cofree are interesting, but I don't think they're programming.That said, I agree that the article doesn't spend a great deal of time explaining the concepts, whether blockchain itself or the category theory it's using, leading to a sense (for me) of being overly terse and coming across as a bit pompous. Although, I realize that for a certain audience there's nothing pompous about this at all and it might seem perfectly reasonable.
OTOH, how many elements should the reader's vocabulary have to enable him to read other's people code?
"A Comonad v is a cofree Comonad for f if every comonad homomorphism from another comonad w to v is equivalent to a natural transformation from w to f.
A cofree functor is right adjoint to a forgetful functor.
Cofree is a functor from the category of functors to the category of comonads that is right adjoint to the forgetful functor from the category of comonads to the category of functors that forgets how to extract and duplicate, leaving you with only a Functor."
So I take it you believe that a degree in category theory is the bare minimum for people to expect to be able to understand other people's code? The layman interpretation of "Avoid success at all costs" comes to mind.
https://hackage.haskell.org/package/lens-4.15.4/docs/Control...
For the blockchain stuff specifically, I suppose I didn't really use them too heavily in this article. So you could argue they aren't currently doing a whole lot of good.
I'm not actually certain if people prefer seeing the heavier types that I default to in real code(to avoid refactoring later), vs. types that are as simple as needed but might need to change as the program evolves. The first choice lets people who already know Haskell learn something from it, while the second makes beginners less confused.
import Control.Monad.Free
import Control.Comonad.Cofree
import Data.Functor.Foldable
data A f
= ANil
| ACons f
type AList a = Cofree A a
a :: AList Int
a = 1 :< ACons (2 :< ACons (3 :< ANil))
data B a f
= B a f
type BList a = Free (B a) ()
b :: BList Int
b = Free (B 1 (Free (B 2 (Free (B 3 (Pure ()))))))
data C a f
= CCons a f
| CNil
type CList a = Fix (C a)
c :: CList Int
c = Fix (CCons 1 (Fix (CCons 2 (Fix (CCons 3 (Fix CNil))))))
You wanted to ensure it's non-empty? Something about the actual Comonad (extend, etc) interface?If cofree seems like it isn't programming, that is only because this style of code helps avoid the need for it.
It's a bit simpler in implementation; the relevant data structures are defined a bit differently, so it could give a nice alternate perspective about what a blockchain written in Haskell may look like.