inexactMatches xs ys = matches xs ys - exactMatches xs ys
then decides it's not very "nice", and ends up with this: inexactMatches = pure2 (-) <**> matches <**> exactMatches
I can sympathize with this preference. When I first started learning Haskell, figuring out how to make something point-free was extremely satisfying. And it also increases DRY, which is generally a good thing.But over time I realized I was overusing point-free style. It was fun to write, but harder to read. If I were actually writing "inexactMatches" for something real, I would strongly prefer the first over the second. From what I've read, I think many people take a similar path when learning Haskell.
That said, I think everyone has a different threshold. For example, I've heard many people say that a for loop is more clear than something like "map" or "fold". I would disagree with that, but maybe that's just because I've gotten used to "map" and "fold".
So maybe the author's brain is just able to handle point-free style better than mine can, but I do think this particular example if far enough on the spectrum that most Haskell programmers would prefer the first version (for real code).
So if you're considering learning Haskell, don't be scared away. You will have to start getting used to point-free style, but probably not to this extreme.
Anyway, I'm well-aware of the temptation of writing point-free code. I did include the sentence "I can see the road to hell is paved with point-free style" myself, after all. I wouldn't prefer point-free style if it ends up looking indiscernible, but in this case I sort of wanted a way to express semi-declaratively "this function is the difference between these other two functions". Does the version I ended up with do that? Yes. But for all I knew there could have been a much better, more idiomatic way.
But yes, that was both a quest to improve that code and a mere learning exercise. I'm satisfied with the version I ended up with, though I don't think it's perfect, either.
As you notice, the poster to whom you are replying clearly goes to a lot of effort to say "the author" repeatedly, rather than 'he' or 'she'. I think that it's fair to assume that one slip-up after such work is a result of innocent inattention rather than a perpetuation of gender biases.
What's being implied here? that because the OP is not omnipotent that there is gender conspiracy?
Broadly making assumptions about everyone within a particular field is as bad if not worse than someone using an incorrect pronoun.
Just as an aside; everyone has to deal with imbeciles in this field whether it be the pointy haired boss or just gross incompetence, it's not gender specific.
> You're going to spend all that work using "the author"
> everywhere and still manage to get my gender wrong
> ("his")?
Where would you have had the commenter go to establish your gender? You haven't attached your name to the article, but even if you had, it's a name that in many countries is male anyway. Would you have rather the commenter have said 'their'?Wow, you got some really hostile reactions for your politely worded comment. Some of those responses belong on @shithnsays
What was there to improve? It's totally sensible and readable, and you even mention that you had people on IRC tell you the function was fine as it is.
For starters you might want to read up on gender neutral pronouns. He/She or his/hers can be used in a gender neutral manner, however traditionally the masculine form is used in English when gender neutral is intended.
In the case of pointfree style, there's a code golf aspect to it as well, it's kinda fun trying to rewrite a particular expression to eliminate variables and maximize the amount of non-alphanumeric characters!
You had some advantages though since you've used Racket in the past.
I feel like your Racket experience helped you draw conclusions that many wouldn't have otherwise. Great work though, I hope you write about more of your experiences.
That said, I'm sure I'm totally influenced by various languages I've tried in the past. And FWIW, Racket was also plenty far from my first experience with functional programming. I know so many programming languages that I've gotten pretty used to being able to just "pick them up" in a couple of days (Racket pretty much included).
Haskell... not so much.
- Knowing to start from scratch and assuming it's some install issue with ghc-mod (this probably saved you a lot of time) - already knowing partial application and that you can use backticks to take advantage of it in Haskell - just knowing what pointfree means - knowing about hoogle - knowing how to search hoogle and what type of function you needed - having an interest in the asthetics of your code leading to experimentation that seems pointless but teaches you a lot - having confidence/knowledge of being able to just plugin functions/types.
As far as conclusions, I'm mostly commenting on the conclusions you simply made from the types... what people sometimes call "type tetris". Knowing you needed `(a, a) -> Bool`, searching hoogle, then coming to the conclusion of I'll implement it myself and moving on.
For a while it seemed like you were going to get caught in "point free hell" and give up on your task... something I've sadly done in the past.
Then knowing to ask for help in #haskell and /r/haskell really helped you.
I know I haven't really answered your question of "what conclusions you'd say they are"... what I was really trying to say is you made a lot of conceptual leaps I wouldn't expect someone with very little Haskell experience to make.
If I remember I'll try to come back to this tomorrow and look for a few examples of those conceptual leaps.
I'd also poke about at the wiki-book 'Write a scheme in 48 hours' (in Haskell) which I've also found useful (although the pdf version has some errors, so I've been preferring the HTML version http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_H... )
Apologies if you've already been through these materials! :)
A reasonably clean way would be to define
data Color = Red | Green | Blue | Yellow | Orange | Purple
deriving (Enum, Bounded, Show)
and then (e.g. in ghci) you can do >> [minBound .. maxBound] :: [Color]
[Red,Green,Blue,Yellow,Orange,Purple]
I often define the useful function enumerate :: (Enum a, Bounded a) => [a]
enumerate = [minBound .. maxBound]
for exactly this purpose.After a while spent programming in Haskell you would probably develop your own mini-library of functions that make your life easier. Another one I often find useful is
(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
(.:) f g = \x y -> f (g x y)
which e.g. allows you to define the absolute distance function dist :: (Num a) => a -> a -> a
dist = abs .: (-)
A fun challenge is figuring out why the definition of (.:) is equivalent to (.:) = fmap . fmap
!"Fine. It's good enough. Moving On." made me laugh! It seems like you thought that could be refactored in a much simpler way. Not knowing (much) Racket, it didn't appear super obvious to me how. Were you alluding to a macro or something? How would you do it in Racket?
I guess I was just hoping that Haskell, being a more composition-oriented language in many ways, would have some nice built-in to do that for me.
: inexact-matches ( x y -- n )
[ matches ] [ exact-matches ] 2bi - ;
That is, run both “matches” and “exact-matches” on both inputs, then take the difference of the results. If Haskell had functions of multiple parameters and results, 2bi’s type would look like this: (a, b, ((a, b) -> c), ((a, b) -> d)) -> (c, d)My long term goal is to write a realtime game server with it, however, I keep flopping back and forth between wrapping my head around the high learning curve and jumping to something more familiar to Get Things Done. It seems the payoff for learning Haskell is intrinsic in and of itself even if I never end up using it, yet I can't help but wonder if I'm spending my time wisely.
It was really refreshing to see somebody write about the struggle to pick up Haskell - indeed, I had a lot of the same issues. I often feel the Haskell community is burdened with this stigma of "if you have to ask questions, you're probably too stupid to get it". This is despite the fact that there is actually a really great group of people always willing to help in #haskell. It's primarily an image problem, one a lot of FP languages suffer from.
We need more articles talking about the pain points of Haskell so we can get better at making this stuff accessible. We need to be honest with new starters, tell them it's okay to find this stuff challenging and show them where to find help. More than that, though, we need to think about what we can do in the language to fix some of these pain points in a way that the community is happy with.
(I would count Haskell as my first 'proper' language, and prior to all this, I had zero coding experience.)
I experienced a lot of the same detours that you have gone through.
re: point-free code
There's a plug in that you can use, called pointfree (cabal install pointfree). I found that it was more useful to me for experimenting with point-free style than writing my own code in that way.
[1] http://learnyouahaskell.com [2] http://haskellrecipes.tumblr.com