简体   繁体   中英

How to curry function with two parameters in Haskell

I have a function buckets with type Integral a => [a] -> Int -> Int -> [[a]] and I want use it in foldl in this way:

basketsort lst = foldl (f) lst [1..3]
f lst = reverse . concat . (flip buckets 9) lst

The function f works, and has a type Integral a => [a] -> Int -> [a] , but if I reduce lst parameter, compilation fails.

Is it possible to reduce more than one parameter by currying and use f 's body in foldl without declaration of f ? Something like this:

basketsort lst = foldl (reverse . concat . (flip buckets 9)) lst [1..3] 

If you expand the second application of the dot operator:

    f lst = reverse . concat . (flip buckets 9) lst
==> f lst = (.) (reverse . concat) ((flip buckets 9) lst)

then the eta-reduction becomes obvious:

    f = (.) (reverse . concat) . (flip buckets 9)

But come on, do you really want to do that? Not a very nice present for whoever is going to maintain your code after you're gone.

First: I recommend not to use flip just to apply a function partially to its second argument; this can be done better with an infix section. (Or, perhaps the arguments of bucket should be the other way around in the first place?)

So, you want to make

f lst = reverse . concat . (`buckets`9) lst

pointfree. The problem is that you need to pass two arguments to the rightmost element in the composition chain. One way to do this is to use uncurried form (because then those two arguments come in just a single value):

f = curry $ reverse . concat . uncurry (`buckets`9)

An alternative is to use specialised combinators. The pointless-fun package has this :

f = reverse . concat .: (`buckets`9)

A more standard, though IMO rather ugly alternative is to use the function-functor: you can map over a function, which corresponds to composing after it:

f = fmap (reverse . concat) . (`buckets`9)

The best alternative frankly is to keep that parameter named:

basketsort lst = foldl (\l -> reverse . concat . buckets l 9) lst [1..3] 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM