If monads are design patterns, then why not rings (Num typeclass), which allow to use addition and multiplication in different contexts? If function composition is a design pattern, then why not function application? If chaining with '>>=' is a design pattern, then is using a semicolon a pattern too? If 'fold', 'map' are patterns, then why not 'sin' and 'cos' are? What is the difference? There's a "pattern" that after sine you put a number; there is also a "pattern" that after a fold you put a function. Thinking that higher-order functions are special is contrary to the spirit of functional programming. Functions and numbers are the same class of citizens, and a function taking a function should not be treated differently from one that takes a number.
Bare names of often-used library functions or language constructs should not be considered patterns, unless they occur as parts of repeating snippets. In this case, you should refactor or encapulate. If you cannot, this is a language flaw. It sucks if you have to type "x = new T(); try { ... } finally { delete x; }" each time. If your language allows to write "using (x = new T()) { ... }" then the pattern is eliminated.
Perhaps there are some "design patterns" in FP, but examples I find often are very weak. One thing that I would count as a pattern is "lift . lift . lift" used in Haskell in monad transformers.
The "lift . lift . lift" expression in multiply stacked monad transformers can often be completely eliminated by using the classes MonadReader, MonadState, MonadIO etc etc, with
putStrLn :: MonadIO m => String -> m ()
ask :: MonadReader r m => m r
modify :: MonadState s m => (s -> s) -> m ()
Now you can define
instance (MonadTrans t, MonadState s m) => MonadState s (t m) where ...
so that any monad transformer applied to a state monad is automatically another state monad. Win!
I agree with you in spirit, but I think your argument for why design patterns aren't present in functional languages can also be used to argue that there are no design patterns in object oriented languages, just by replacing the word "function" with the word "object". Witness:
Thinking that objects are special is contrary to the spirit of object-oriented programming. Objects and numbers are the same class of citizens, and a method taking an object should not be treated differently from one that takes a number.
Would you also argue that there are no (or very few) design patterns in object oriented languages?
I was trying to say that using higher-order functions (or functions taking objects) is not automatically a design pattern; a pattern must consist of a larger group of code. Patterns show up where abstractions provided by language are not powerful enough to capture analogies.
If monads are design patterns, then why not rings (Num typeclass), which allow to use addition and multiplication in different contexts? If function composition is a design pattern, then why not function application? If chaining with '>>=' is a design pattern, then is using a semicolon a pattern too? If 'fold', 'map' are patterns, then why not 'sin' and 'cos' are? What is the difference? There's a "pattern" that after sine you put a number; there is also a "pattern" that after a fold you put a function. Thinking that higher-order functions are special is contrary to the spirit of functional programming. Functions and numbers are the same class of citizens, and a function taking a function should not be treated differently from one that takes a number.
Bare names of often-used library functions or language constructs should not be considered patterns, unless they occur as parts of repeating snippets. In this case, you should refactor or encapulate. If you cannot, this is a language flaw. It sucks if you have to type "x = new T(); try { ... } finally { delete x; }" each time. If your language allows to write "using (x = new T()) { ... }" then the pattern is eliminated.
Perhaps there are some "design patterns" in FP, but examples I find often are very weak. One thing that I would count as a pattern is "lift . lift . lift" used in Haskell in monad transformers.