Learn You a Haskell demonstrates mapping with currying:
*Main> let xs = map (*) [1..3]
xs now equals [(1*), (2*), (3*)]
EDITED to correct order per Antal S-Z's comment.
We can get the first item in the list, and apply 3 to it - returning 3*1.
*Main> (xs !! 0) 3
3
But, how can I apply the below foo to apply 1 to all curried functions in xs?
*Main> let foo = 1
*Main> map foo xs
<interactive>:160:5:
Couldn't match expected type `(Integer -> Integer) -> b0'
with actual type `Integer'
In the first argument of `map', namely `foo'
In the expression: map foo xs
In an equation for `it': it = map foo xs
Desired output:
[1, 2, 3]
Use the ($) function...
Prelude> :t ($)
($) :: (a -> b) -> a -> b
...passing just the second argument to it.
Prelude> let foo = 2
Prelude> map ($ foo) [(1*), (2*), (3*)]
[2,4,6]
Have you tried using applicative functors?
import Control.Applicative
main = (*) <$> [1,2,3] <*> pure 1
The <$> function is the same as fmap in infix form. It has the type signature:
(<$>) :: Functor f => (a -> b) -> f a -> f b
The <*> function is the functor equivalent of $ (function application):
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
The pure function is similar to return for monads. It takes a normal value and returns an applicative functor:
pure :: Applicative f => a -> f a
Hence the expression (*) <$> [1,2,3] <*> pure 1 is similar to applying the (*) function to all the values of [1,2,3] and pure 1. Since pure 1 only has one value it is equivalent to multiplying every item of the list with 1 to produce a new list of products.
Or you could use anonymous function:
map (\x -> x foo) xs
Related
I have a problem with understanding what the compiler does when I enter this:
(curry . uncurry) (+) 1 2
After my understanding the compiler goes with uncurry first which would mean that an error would occur because the uncurry function needs an input like this:
(curry . uncurry) (+) (1,2)
but obviously the first one is right. I don't get why though.
What exactly are the steps the compiler takes when evaluating this?
Another topic included question:
Why does
(uncurry . curry) (+) (1,2)
does not work?
After my understanding the compiler goes with uncurry.
No it goes with the (curry . uncurry)
If we evaluate the (curry . uncurry) function we see that this short for:
\x -> curry (uncurry x)
so the (curry . uncurry) (+) 1 2 function is short for:
(\x -> curry (uncurry x)) (+) 1 2
or thus:
(curry (uncurry (+))) 1 2
and uncurry :: (a -> b -> c) -> (a, b) -> c and curry :: ((a, b) -> c) -> a -> b -> c thus transform a function. This thus means that uncurry (+) indeed expects a 2-tuple:
uncurry (+) :: Num a => (a, a) -> a
but now pass this function through the curry function:
curry (uncurry (+)) :: Num a => a -> a -> a
so the curry function undoes the transformation the uncurry made to the (+) function. This thus means that curry (uncurry (+)) is the same as (+), and thus:
(curry (uncurry (+))) 1 2
is equivalent to:
(+) 1 2
and this is thus equivalent to 3.
The curry . uncurry is not completely equivalent to id however, since it has as type:
curry . uncurry :: (a -> b -> c) -> a -> b -> c
this thus means that it restricts the function to a function of type a -> (b -> c).
Your expression parses as
(((curry . uncurry) (+)) 1) 2
so, it builds the function (curry . uncurry) (+) and applies it to 1, then the resulting function is applied to 2.
Hence, we start from (curry . uncurry) (+) which means curry (uncurry (+)). Assume for simplicity that (+) is implemented as
(+) = \x y -> ...
Note the above is an curried function, taking x and then y as separate arguments. We then have:
curry (uncurry (+))
= { definition + }
curry (uncurry (\x y -> ...)) -- note the separate arguments
= { definition uncurry }
curry (\(x, y) -> ...) -- only one pair argument
= { definition curry }
(\x y -> ...) -- back to two arguments
= { definition + }
(+)
Above, uncurry transforms the function + into one that accepts a single pair argument instead of two. This transformation is reversed by curry, which breaks the pair argument into two separate ones.
Indeed, curry . uncurry is the identity transformation on binary curried functions since it applies a transformation and its inverse. Hence, it has no effect on the result, or on the type of the functions involved.
We conclude that your expression is equivalent to ((+) 1) 2, which evaluates to 3.
This question got great answers, yet I would like to add a note about curry . uncurry.
You might have heard of SKI-calculus. If you haven't, it is a calculus where we work with 3 combinators:
Sabc = ac(bc)
Kab = a
Ia = a
It is widely known to be Turing-full.
Besides, the I combinator is redundant. Let us try writing it down in terms of S and K combinators.
The main idea is that the only argument of I should be passed as the first argument of K, whose second argument is occupied. That is exactly what the S combinator does: if we pass K as the first argument of S, we would have it return the third argument of S:
SKbc = Kc(bc) = c
We have shown that (K*ab = b):
K* = SK
Therefore, we just need to choose the second argument: both K and S would do:
I = SKK = SKS
As one can see, combinator I corresponds to id;
combinator K corresponds to const;
and combinator S corresponds to (<*>) :: (e -> a -> b) -> (e -> a) -> e -> b.
I = SKK corresponds to const <*> const :: a -> a.
Our other results (I = SKS and K* = SK) do not hold in Haskell due to typing:
GHCi> :t (<*>) const (<*>) {- id -}
(<*>) const (<*>) {- id -}
:: Applicative f => f (a -> b) -> f (a -> b)
GHCi> :t (const <*>) {- flip const -}
(const <*>) {- flip const -} :: (b -> a) -> b -> b
As one can see, our implementations act as the required functions on their domain, but we narrowed the domains down.
If we specify (<*>) const (<*>) to the reader, we get exactly the function you wrote down as curry . uncurry - id for functions.
Another workalike for curry . uncurry is ($):
f $ x = f x
($) f x = f x
($) f = f
($) = id
The function you found is very interesting - it might be a good exercise to look for other workalikes (I don't know whether there are any other notable ones out there).
Hello i am trying to do the following:
module MyMonad where
f::(Monad m),=>m (a->b->c)->m a -> m b -> m c
f mf ma mb=
ma >>= \a ->
mb >>= \b ->
mf >>= \c ->
return (c a b)
and use it like this :
f (Just 3) (Just 4)
And i get the following error:
* Non type-variable argument in the constraint: Num (a -> b -> c)
(Use FlexibleContexts to permit this)
* When checking the inferred type
it :: forall a b c.
(Num a, Num (a -> b -> c)) =>
Maybe b -> Maybe c
I didn't know how to put multiple type constraints so i tried like this:
f (Just [3]) (Just [4]) (++) -- (knowing (++) can be applied to any type - being a monoid).
In this case i get the following exception:
* Couldn't match expected type `Maybe b0'
with actual type `[a1] -> [a1] -> [a1]'
* Probable cause: `(++)' is applied to too few arguments
In the third argument of `f', namely `(++)'
In the expression: f (Just [3]) (Left [3]) (++)
In an equation for `it': it = f (Just [3]) (Left [3]) (++)
f requires a monad-wrapped function as the first argument. In your first try, you didn't pass the function at all; in the second, you pass (++) as the last argument.
The following works fine:
> f (Just (++)) (Just [3]) (Just [4])
Just [3,4]
liftM2 (and more generally liftA2) already does something very similar to what you want.
> import Control.Monad (liftM2)
> liftM2 (++) (Just [3]) (Just [4])
Just [3,4]
> import Control.Applicative (liftA2)
> liftA2 (++) (Just [3]) (Just [4])
Just [3,4]
Consider the following function:
foo =
[1,2,3] >>=
return . (*2) . (+1)
For better readability and logic, I would like to move my pure functions (*2) and (+1) to the left of the return. I could achieve this like this:
infixr 9 <.
(<.) :: (a -> b) -> (b -> c) -> (a -> c)
(<.) f g = g . f
bar =
[1,2,3] >>=
(+1) <.
(*2) <.
return
However, I don't like the right-associativity of (<.).
Let's introduce a function leftLift:
leftLift :: Monad m => (a -> b) -> a -> m b
leftLift f = return . f
baz =
[1,2,3] >>=
leftLift (+1) >>=
leftLift (*2) >>=
return
I quite like this. Another possibility would be to define a variant of bind:
infixl 1 >>$
(>>$) :: Monad m => m a -> (a -> b) -> m b
(>>$) m f = m >>= return . f
qux =
[1,2,3] >>$
(+1) >>$
(*2) >>=
return
I am not sure whether that is a good idea, since it would not allow me to use do notation should I want that. leftLift I can use with do:
bazDo = do
x <- [1,2,3]
y <- leftLift (+1) x
z <- leftLift (*2) y
return z
I didn't find a function on Hoogle with the signature of leftLift. Does such a function exist, and, if, what is it called? If not, what should I call it? And what would be the most idiomatic way of doing what I am trying to do?
Edit: Here's a version inspired by #dunlop's answer below:
infixl 4 <&>
(<&>) :: Functor f => f a -> (a -> b) -> f b
(<&>) = flip fmap
blah =
[1,2,3] <&>
(+1) <&>
(*2) >>=
return
I should also add that I was after a bind-variant, because I wanted to write my code in point-free style. For do-notation, I guess I don't need to "pretend" that I'm doing anything monadic, so I can use lets.
Every Monad is a Functor (and an Applicative too). Your (>>$) is (flipped) fmap.
GHCi> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
GHCi> :t (<$>) -- Infix synonym for 'fmap'
(<$>) -- Infix synonym for 'fmap'
:: Functor f => (a -> b) -> f a -> f b
GHCi> fmap ((*2) . (+1)) [1,2,3]
[4,6,8]
GHCi> (*2) . (+1) <$> ([1,2,3] >>= \x -> [1..x])
[4,4,6,4,6,8]
(By the way, a common name for flipped fmap is (<&>). That is, for instance, what lens calls it.)
If you are using do-notation, there is little reason to use any variant of fmap explicitly for this kind of transformation. Just switch your <- monadic bindings for let-bindings:
bazDo = do
x <- [1,2,3]
let y = (+1) x
z = (*2) y
return z
bazDo = do
x <- [1,2,3]
let y = (+1) x
return ((*2) z)
For better readability...
That's going to be subjective as people disagree on what constitutes readable.
That being said, I agree that sometimes it's easier to understand data transformations when they are written left to right. I think your >>$ is overkill, though. The & operator in Data.Function does the job:
import Data.Function
foo = [1,2,3] & fmap (+1) & fmap (*2)
I like that this says exactly what to start with and exactly what to do at each step from left to right. And unlike >>$, you aren't forced to remain in the monad:
bar = [1,2,3] & fmap (+1) & fmap (*2) & sum & negate
Or you can just assemble your transformation beforehand and map it over your monad:
import Control.Category
f = (+1) >>> (*2)
quuz = fmap f [1,2,3]
I'm trying to understand what Kleisli, i.e. >=>, provides over bind (>>=).
Looking at their signatures of bind and Klesli, respectively:
λ: :t (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
λ: :t (>=>)
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
And then this example:
λ: let plus10 = \x -> return (x + 10)
λ: let minus5 = \x -> return (x - 5)
I can use either function call:
λ: return 5 >>= plus10 >>= minus5
10
λ: (>=>) plus10 minus5 5
10
Of course this is a single, simple example. However, what is the importance of Kleisli over bind? From looking at their function definitions, I wonder if every Kleisli function usage can be re-written using bind.
It's similar more or less to the difference between (.) and ($) (or function application).
For example, if I wanted to count the number of even numbers in a list, I could do:
countEven = length . filter even
Or I could do
countEven xs = length $ filter even $ xs
Which really are the same thing, and compile/inline to the same thing in the end, but the two "mean" different things.
The first one says, "countEven is the length of an even-filtered list". The second one says, "to get the number of evens in this list, filter it with filter even, and then apply length to the result".
Different ways of saying the same thing. And you could definitely implement one each in terms of the other:
f . g = \x -> f $ g $ x
As Justin said it's like .. You can rewrite your example as (>=>) plus10 minus5 5 as return 5 >>= (plus10 >=> plus5), you can compare easily the two version
λ: return 5 >>= plus10 >>= minus5
10
λ: return 5 >>= (plus10 >=> minus5)
10
In other word, if you want to write a a point-free version, you can't just write plus10 >>= minus5, you need to use >=> instead.
This is working
unique :: (a -> Bool) -> [a] -> Bool
unique p xs = 1 == length (filter p xs)
But now I want it in the form:
unique = (== 1) . length . filter
Error message:
Couldn't match expected type `[a] -> Bool' with actual type `Bool'
Expected type: b0 -> [a] -> Bool
Actual type: b0 -> Bool
In the first argument of `(.)', namely `(== 1)'
In the expression: (== 1) . length . filter
Why is this not working?
This is because filter is a two argument function. You can get around this using the handy operator
(.:) = (c -> d) -> (a -> b -> c) -> a -> b -> d
(.:) = (.) . (.)
-- Important to make it the same precedence as (.)
infixr 9 .:
unique = ((== 1) . length) .: filter
If you look at the type of (length .) in GHCi, you'll get
(length .) :: (a -> [b]) -> a -> Int
This means that it takes a single argument function that returns a list. If we look at the type of filter:
filter :: (a -> Bool) -> [a] -> [a]
This can be rewritten to make it "single argument" as
filter :: (a -> Bool) -> ([a] -> [a])
And this quite clearly does not line up with a -> [b]! In particular, the compiler can't figure out how to make ([a] -> [a]) be the same as [b], since one is a function on lists, and the other is simply a list. So this is the source of the type error.
Interestingly, the .: operator can be generalized to work on functors instead:
(.:) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
(.:) = fmap fmap fmap
-- Since the first `fmap` is for the (->) r functor, you can also write this
-- as (.:) = fmap `fmap` fmap === fmap . fmap
What is this good for? Say you have a Maybe [[Int]], and you wanted the sum of each sublist inside the Just, provided it exists:
> let myData = Just [[3, 2, 1], [4], [5, 6]]
> sum .: myData
Just [6, 4, 11]
> length .: myData
Just [3, 1, 2]
> sort .: myData
Just [[1,2,3],[4],[5,6]]
Or what if you had a [Maybe Int], and you wanted to increment each one:
> let myData = [Just 1, Nothing, Just 3]
> (+1) .: myData
[Just 2,Nothing,Just 4]
The possibilities go on and on. Basically, it lets you map a function inside two nested functors, and this sort of structure crops up pretty often. If you've ever had a list inside a Maybe, or tuples inside a list, or IO returning a string, or anything like that, you've come across a situation where you could use (.:) = fmap fmap fmap.