问题
I finally got bored enough in quarantine to start learning Haskell today and I'm really enjoying myself, I really love the aesthetics of the language. Hopefully this question doesn't inspire any hate if it has already been posted here before, etc. It's very simple, but I'm an absolute beginner.
I've been trying to understand how to do some simple things elegantly (or at least in a so-called "point free" way) with the language and came upon the problem of how to describe in a clean way the procedure of taking a function of two variables and restricting it to the graph of a function between the two variables. E.g. how to take a function of two variables of the same type and restrict it along the diagonal to obtain a function of one variable with the same type and the same type of outputs, or any similar problem (a bit like trying currying on the wrong side of the hom, if you like).
I was messing around today with concise ways of doing this but eventually gave up and implemented the following for later use:
compFtn :: (a -> b -> c) -> (a -> b) -> a -> c
compFtn f g a = f a (g(a))
which does what I wanted (as would, say, decurrying f and doing this in a really ugly fashion). However I have a feeling that there must be a way more "point free"/doctrinaire solution to this very basic operation, so I'm here asking around to learn some style from y'all. Cheers.
回答1:
A function is a functor, an applicative and a monad. We may consider functions as a context with a contained value revealed once applied.
So for a function type Functor
instance would be the composition (.)
operator. Why? Lets say we have a function (+1)
which says when you apply me a Num a
class value i will increment it by 1. So lets implement fmap
.
fmap f g = f . g -- <$> == (.)
obviously we are applying f
to the return value of g
.
So how can we make a function an instance of Applicative? It must contain another function in its context. Basically it should return a function when applied. This means (a -> b -> c)
at least. So here you go.
(a -> b -> c) <*> (a -> b)
is in fact once a
is applied (a -> b -> c)
becomes (b -> c)
and (a -> b)
becomes b
and (b -> c)
gets applied with the b
. So yes what you are looking for is <*>
operator.
来源:https://stackoverflow.com/questions/61907072/is-there-a-pretty-glib-way-to-restrict-a-curry-ed-function-to-the-graph-of-anoth