i.e. when browsing and trying to understand parts of the XMonad code, I came across the "Endo" type. I Hoogle'd it, and the only documentation for it is "newtype Endo a: The monoid of endomorphisms under composition." Thats.... not helpful for me.
i.e. when browsing and trying to understand parts of the XMonad code, I came across the "Endo" type. I Hoogle'd it, and the only documentation for it is "newtype Endo a: The monoid of endomorphisms under composition." Thats.... not helpful for me.
-- Endo is…
newtype Endo a
= Endo { appEndo :: a -> a }
-- ^
-- |
-- …the monoid of endomorphisms…
-- |
-- V
instance Monoid (Endo a) where
mappend (Endo f) (Endo g)
= Endo (f . g)
-- ^
-- |
-- …under composition.
mempty = Endo id
But not so much about how to actually use it: -- If you’ve got a list of functions…
pipeline :: [Int -> Int]
pipeline = [(+ 3), (* 2), abs]
-- …you can compose them with the generic mconcat.
run :: [a -> a] -> a -> a
run = appEndo . mconcat . map Endo
run pipeline (-1) == 5---
Reply to montatonic here:
I'm neither a Haskeller nor do I want to see Haskell “take over” the world. Some of my comments even got lots of downvotes from Haskellers.
---
Reply to sidlls here:
Yes, FWIW, I don't really agree with the use of the term “endomorphism”. It isn't even precise: the type `Endo` is inhabited by endomorphisms is one specific category (Hask), not endomorphisms in arbitrary categories. So “endofunction” would be both more accurate and less pompous.
As for “codomain”, I can't agree, though. This is really high school stuff.
Neophyte: Hello, I do not understand this.
Haskeller: You should already know this.
twice :: Integer -> Integer
twice = (2*)
Here, `twice`'s range contains just the even integers.As a haskeller myself I wholeheartedly disagree. I knew nothing of function composition until Haskell. I only heard about functions in high school once my senior year and it was very basic. Admittedly I went to high school in rural Texas.
I also never heard about sets, the word I was never used in my high school math classes.
> this is stuff that every high school graduate should know.
You seem to have a lot of faith in the lowest common denominator of high school graduates and I think it does you a disservice in being able to help others learn these topics.
I sense my last paragraph might have sounded a bit... Aggressive? That's not my intention.
P.S. I still don't really know what domain and codomain mean :)
If the material is taught in high school, then educators must have decided that high schoolers can learn it, right?
> I still don't really know what domain and codomain mean :)
someFunction :: Domain -> CodomainDid you miss that I said it wasn't taught in my school?
https://www.youtube.com/watch?v=I8LbkfSSR58 https://bartoszmilewski.com/2014/10/28/category-theory-for-p...
For example, the poster you replied to can only see the advantage being that his question is answered. The tangible benefit for taking time out of the day to go and read those foundations needs to be made more clear I think.
y1 = f_1 x
y = f_2 y1
-- or,
y = f_2 (f_1 x)
But what if you have an arbitrary list of functions as your pipeline? y = f_n (f_{n-1} (... (f_2 (f_1 x)) ...))
Well, the solution is that functions of type `a -> a` are composeable, so you can 'add them up' as if they were real values (which they are). The Haskell function composition operator is `.`, so: y = f_2 (f_1 x)
-- is the same as,
y = (f_2 . f_1) x
Now, how do you go from 'composing two functions' to 'composing a list of functions'? Well, monoids are a typeclass (a statically-enforceable design pattern) that encode the idea of being able to combine two things into one, and 'for free' give you a function `mconcat` that combines a list of those things into one. So if you have a monoid instance for functions of type `a -> a`, you're now able to combine many of them together, get a single composed function, and apply your input value `x` to that.`Endo` is just a fancy name for 'function of type `a -> a`'. I agree to a large extent that all this category theory stuff can get distracting. I personally think type theory is a much more rewarding field of study. To 'endomorphism', a type theorist would say, 'Oh, you mean `a -> a`?'
(I know "+1" posts are a sin, but if a few more haskellers take heed of the documentation problem, it'll be worth me getting hellbanned.)
This module is inspired by the following paper: <DOI>If you aren't planning on submitting that to those docs I will. In fact I'm sure many would find you adding examples along those lines to the most popular but math inspired Haskell libraries.
-- Using Elm syntax
pipeline : List (Int -> Int)
pipeline = [(\x -> x + 3), (\x -> x * 2), abs]
applyPipeline : Int -> Int
applyPipeline value = List.foldr (\func val -> func val) value pipeline
-- or more succinctly
applyPipeline_ value = List.foldr (<|) value pipeline
Getting lost in the mathematical abstractions is really no help here. In niche circumstances I'm sure it's great, but like.... not here.
The language itself doesn't demand we write code this way, but the community, understandably, loves to be as expressive as possible in many cases.
But all of this comes with a cost of cognitive overhead that seems to rarely be worth paying.
Elm was an enlightening experience for me, having started with Haskell, because it helped me to realize just how little I ever took advantage of a lot of the very generic Haskell code, and how far the simplest of functions and types could take you in the overwhelming majority of cases.
To quote from Paul's post: "The trouble is that very often, the sorts of examples that are easy to discuss aren’t of sufficient scale to reveal any major differences between A and B."
---
Reply to sidlls here:
I didn't say that the term might sound scary to you. I said that the term might sound scary in general, to “average” people. Because, frankly, relative to its actual mathematical content, the term is perhaps a little bit too pompous.
Also, when it comes to mathematical definitions, I wouldn't say one really knows a definition unless one can use it in a calculational setting.
(terse && correct) != helpful
The art in writing documentation is in effective communication to a varied target audience, not in simply fulfilling the obligation to be technically correct.However:
(0) As for “endomorphism”, the definition “function with the same domain and codomain” should be pretty easy to understand to anyone. (Technically, in an arbitrary category, morphisms don't have to be functions, but Haskellers work in the category Hask, whose morphisms are terminating functions.)
(1) The right place to define what a monoid is is the definition of the class Monoid, not the definition of every type that happens to have a Monoid instance.
This is my favourite haskellism so far in this thread.
I learned the jargon as part of my academic background. That was part of the reason I made the comment. These terms are jargon, or terms-of-art. Knowing jargon isn't the same as knowing the things jargon describes or having the capacity to reason about them well. Similarly, not knowing the jargon does not imply ignorance, stupidity, fear, or any of a number of other negative things.