Confusion around when to compose, and when to use $

Multi tool use
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
returnGreater :: (Ord a) => a -> a -> a
returnGreater a b
| (a > b) = a
| otherwise = b
returnGreatest2 :: (Ord a, Num a) => a -> a -> a -> (a, a)
returnGreatest2 a b c
| (a > b) = (a, returnGreater b c)
| otherwise = (b, returnGreater a c)
sumOfSquares :: (Num a) => (a, a) -> a
sumOfSquares (a, b) = a^2 + b^2
Given the above functions, I'm confused why let x = sumOfSquares . returnGreatest2
returns
<interactive>:13:24: error:
• Couldn't match type ‘a -> a -> (a, a)’ with ‘(c, c)’
Expected type: a -> (c, c)
Actual type: a -> a -> a -> (a, a)
• Probable cause: ‘returnGreatest2’ is applied to too few arguments
In the second argument of ‘(.)’, namely ‘returnGreatest2’
In the expression: sumOfSquares . returnGreatest2
In an equation for ‘x’: x = sumOfSquares . returnGreatest2
• Relevant bindings include
x :: a -> c (bound at <interactive>:13:5)
but sumOfSquares $ returnGreatest2 3 5 7
does the right thing. Since the type coming out of returnGreatest2
is the same as the type sumOfSquares
expects, I would think I'd be able to compose them.
haskell
add a comment |
returnGreater :: (Ord a) => a -> a -> a
returnGreater a b
| (a > b) = a
| otherwise = b
returnGreatest2 :: (Ord a, Num a) => a -> a -> a -> (a, a)
returnGreatest2 a b c
| (a > b) = (a, returnGreater b c)
| otherwise = (b, returnGreater a c)
sumOfSquares :: (Num a) => (a, a) -> a
sumOfSquares (a, b) = a^2 + b^2
Given the above functions, I'm confused why let x = sumOfSquares . returnGreatest2
returns
<interactive>:13:24: error:
• Couldn't match type ‘a -> a -> (a, a)’ with ‘(c, c)’
Expected type: a -> (c, c)
Actual type: a -> a -> a -> (a, a)
• Probable cause: ‘returnGreatest2’ is applied to too few arguments
In the second argument of ‘(.)’, namely ‘returnGreatest2’
In the expression: sumOfSquares . returnGreatest2
In an equation for ‘x’: x = sumOfSquares . returnGreatest2
• Relevant bindings include
x :: a -> c (bound at <interactive>:13:5)
but sumOfSquares $ returnGreatest2 3 5 7
does the right thing. Since the type coming out of returnGreatest2
is the same as the type sumOfSquares
expects, I would think I'd be able to compose them.
haskell
2
I'll give you a hint. What is the type of the composition operator(.)
?
– jkeuhlen
Nov 15 '18 at 17:31
2
Remember that type of(.) :: (b -> c) -> (a -> b) -> a -> c
. HoweverreturnGreatest2
takes 4 parameters so it shall be applied with 3 parameters (until its type becomesa -> (a,a)
or as in the above type signature(a -> b)
and only then you can apply it to composition operator. Such aslet x = sumOfSquares . returnGreatest 2 3 5
and thenx 7
will give you the result.
– Redu
Nov 15 '18 at 17:43
1
Here’s a short derivation of how to convert compositions of multiple arguments like this to point-free form.x y z -> g ((f x y) z)
=(definition of composition)=x y -> g . f x y
=(rewrite in prefix)=x y -> ((.) g) ((f x) y)
=(definition of composition)=x -> (.) g . f x
=(rewrite in prefix)=x -> ((.) ((.) g)) (f x)
=(definition of composition)=(.) ((.) g) . f
=(instance Functor ((->) a)
)=fmap (fmap g) . f
. Hereg
=sumOfSquares
andf
=returnGreatest2
. In general, to compose a 1-argument function with an n-argument function you need tofmap
n − 1 times.
– Jon Purdy
Nov 17 '18 at 2:11
add a comment |
returnGreater :: (Ord a) => a -> a -> a
returnGreater a b
| (a > b) = a
| otherwise = b
returnGreatest2 :: (Ord a, Num a) => a -> a -> a -> (a, a)
returnGreatest2 a b c
| (a > b) = (a, returnGreater b c)
| otherwise = (b, returnGreater a c)
sumOfSquares :: (Num a) => (a, a) -> a
sumOfSquares (a, b) = a^2 + b^2
Given the above functions, I'm confused why let x = sumOfSquares . returnGreatest2
returns
<interactive>:13:24: error:
• Couldn't match type ‘a -> a -> (a, a)’ with ‘(c, c)’
Expected type: a -> (c, c)
Actual type: a -> a -> a -> (a, a)
• Probable cause: ‘returnGreatest2’ is applied to too few arguments
In the second argument of ‘(.)’, namely ‘returnGreatest2’
In the expression: sumOfSquares . returnGreatest2
In an equation for ‘x’: x = sumOfSquares . returnGreatest2
• Relevant bindings include
x :: a -> c (bound at <interactive>:13:5)
but sumOfSquares $ returnGreatest2 3 5 7
does the right thing. Since the type coming out of returnGreatest2
is the same as the type sumOfSquares
expects, I would think I'd be able to compose them.
haskell
returnGreater :: (Ord a) => a -> a -> a
returnGreater a b
| (a > b) = a
| otherwise = b
returnGreatest2 :: (Ord a, Num a) => a -> a -> a -> (a, a)
returnGreatest2 a b c
| (a > b) = (a, returnGreater b c)
| otherwise = (b, returnGreater a c)
sumOfSquares :: (Num a) => (a, a) -> a
sumOfSquares (a, b) = a^2 + b^2
Given the above functions, I'm confused why let x = sumOfSquares . returnGreatest2
returns
<interactive>:13:24: error:
• Couldn't match type ‘a -> a -> (a, a)’ with ‘(c, c)’
Expected type: a -> (c, c)
Actual type: a -> a -> a -> (a, a)
• Probable cause: ‘returnGreatest2’ is applied to too few arguments
In the second argument of ‘(.)’, namely ‘returnGreatest2’
In the expression: sumOfSquares . returnGreatest2
In an equation for ‘x’: x = sumOfSquares . returnGreatest2
• Relevant bindings include
x :: a -> c (bound at <interactive>:13:5)
but sumOfSquares $ returnGreatest2 3 5 7
does the right thing. Since the type coming out of returnGreatest2
is the same as the type sumOfSquares
expects, I would think I'd be able to compose them.
haskell
haskell
edited Nov 15 '18 at 17:39
Mark Seemann
185k33330570
185k33330570
asked Nov 15 '18 at 17:18


flybonzaiflybonzai
1,25011738
1,25011738
2
I'll give you a hint. What is the type of the composition operator(.)
?
– jkeuhlen
Nov 15 '18 at 17:31
2
Remember that type of(.) :: (b -> c) -> (a -> b) -> a -> c
. HoweverreturnGreatest2
takes 4 parameters so it shall be applied with 3 parameters (until its type becomesa -> (a,a)
or as in the above type signature(a -> b)
and only then you can apply it to composition operator. Such aslet x = sumOfSquares . returnGreatest 2 3 5
and thenx 7
will give you the result.
– Redu
Nov 15 '18 at 17:43
1
Here’s a short derivation of how to convert compositions of multiple arguments like this to point-free form.x y z -> g ((f x y) z)
=(definition of composition)=x y -> g . f x y
=(rewrite in prefix)=x y -> ((.) g) ((f x) y)
=(definition of composition)=x -> (.) g . f x
=(rewrite in prefix)=x -> ((.) ((.) g)) (f x)
=(definition of composition)=(.) ((.) g) . f
=(instance Functor ((->) a)
)=fmap (fmap g) . f
. Hereg
=sumOfSquares
andf
=returnGreatest2
. In general, to compose a 1-argument function with an n-argument function you need tofmap
n − 1 times.
– Jon Purdy
Nov 17 '18 at 2:11
add a comment |
2
I'll give you a hint. What is the type of the composition operator(.)
?
– jkeuhlen
Nov 15 '18 at 17:31
2
Remember that type of(.) :: (b -> c) -> (a -> b) -> a -> c
. HoweverreturnGreatest2
takes 4 parameters so it shall be applied with 3 parameters (until its type becomesa -> (a,a)
or as in the above type signature(a -> b)
and only then you can apply it to composition operator. Such aslet x = sumOfSquares . returnGreatest 2 3 5
and thenx 7
will give you the result.
– Redu
Nov 15 '18 at 17:43
1
Here’s a short derivation of how to convert compositions of multiple arguments like this to point-free form.x y z -> g ((f x y) z)
=(definition of composition)=x y -> g . f x y
=(rewrite in prefix)=x y -> ((.) g) ((f x) y)
=(definition of composition)=x -> (.) g . f x
=(rewrite in prefix)=x -> ((.) ((.) g)) (f x)
=(definition of composition)=(.) ((.) g) . f
=(instance Functor ((->) a)
)=fmap (fmap g) . f
. Hereg
=sumOfSquares
andf
=returnGreatest2
. In general, to compose a 1-argument function with an n-argument function you need tofmap
n − 1 times.
– Jon Purdy
Nov 17 '18 at 2:11
2
2
I'll give you a hint. What is the type of the composition operator
(.)
?– jkeuhlen
Nov 15 '18 at 17:31
I'll give you a hint. What is the type of the composition operator
(.)
?– jkeuhlen
Nov 15 '18 at 17:31
2
2
Remember that type of
(.) :: (b -> c) -> (a -> b) -> a -> c
. However returnGreatest2
takes 4 parameters so it shall be applied with 3 parameters (until its type becomes a -> (a,a)
or as in the above type signature (a -> b)
and only then you can apply it to composition operator. Such as let x = sumOfSquares . returnGreatest 2 3 5
and then x 7
will give you the result.– Redu
Nov 15 '18 at 17:43
Remember that type of
(.) :: (b -> c) -> (a -> b) -> a -> c
. However returnGreatest2
takes 4 parameters so it shall be applied with 3 parameters (until its type becomes a -> (a,a)
or as in the above type signature (a -> b)
and only then you can apply it to composition operator. Such as let x = sumOfSquares . returnGreatest 2 3 5
and then x 7
will give you the result.– Redu
Nov 15 '18 at 17:43
1
1
Here’s a short derivation of how to convert compositions of multiple arguments like this to point-free form.
x y z -> g ((f x y) z)
=(definition of composition)= x y -> g . f x y
=(rewrite in prefix)= x y -> ((.) g) ((f x) y)
=(definition of composition)= x -> (.) g . f x
=(rewrite in prefix)= x -> ((.) ((.) g)) (f x)
=(definition of composition)= (.) ((.) g) . f
=(instance Functor ((->) a)
)= fmap (fmap g) . f
. Here g
= sumOfSquares
and f
= returnGreatest2
. In general, to compose a 1-argument function with an n-argument function you need to fmap
n − 1 times.– Jon Purdy
Nov 17 '18 at 2:11
Here’s a short derivation of how to convert compositions of multiple arguments like this to point-free form.
x y z -> g ((f x y) z)
=(definition of composition)= x y -> g . f x y
=(rewrite in prefix)= x y -> ((.) g) ((f x) y)
=(definition of composition)= x -> (.) g . f x
=(rewrite in prefix)= x -> ((.) ((.) g)) (f x)
=(definition of composition)= (.) ((.) g) . f
=(instance Functor ((->) a)
)= fmap (fmap g) . f
. Here g
= sumOfSquares
and f
= returnGreatest2
. In general, to compose a 1-argument function with an n-argument function you need to fmap
n − 1 times.– Jon Purdy
Nov 17 '18 at 2:11
add a comment |
3 Answers
3
active
oldest
votes
Composition and currying can be a little confusing. sumOfSquares . returnGreatest2
is the same as x -> sumOfSquares (returnGreatest2 x)
, but the type of returnGreatest2 x
is (Ord a, Num a) => a -> a -> (a, a)
. You need to pass all expected arguments before you finally get a value of type (Ord a, Num a) => (a, a)
that is acceptable by sumOfSquares
.
On the other hand, sumOfSquares $ returnGreatest2 3 5 7
is parsed the same as sumOfSquares $ (returnGreatest2 3 5 7)
; the ($)
operator has lower priority than function application (or any other operator, for that matter).
To really compose the two functions, you need several layers of composition:
let f = ((sumOfSquares .) . ) . returnGreatest2
1
I prefer to write the point-free version asfmap (fmap sumOfSquares) . returnGreatest2
. Thefmap
is the same as(.)
here (in the(->) _
functor) but imo is clearer: eachfmap
“maps over” one argument. Including extra parentheses for clarity,fmap (fmap sumOfSquares)
is specialised to the type(a -> a -> (a, a)) -> (a -> a -> a)
, making it composable withreturnGreatest2 :: a -> (a -> a -> (a, a))
.
– Jon Purdy
Nov 17 '18 at 0:43
add a comment |
Both sides of (.)
function are expected to be a single argument functions so it treats returnGreatest2
as a a -> (a -> a -> (a, a))
. But sumOfSquares
does not accept (a -> a -> (a, a))
as an argument. One way to do it is to use $
like you did and apply all the arguments, but you can also state first two arguments explicitly:
let x a b = sumOfSquares . returnGreatest2 a b
x :: (Num c, Ord c) => c -> c -> c -> c
this way the types will match.
add a comment |
You can try this
sumOfSquares . returnGreatest2 3 5 $ 7
$
has te lowest priority. returnGreatest2 3 5
is the function returnGreatest2
partially applied to 3
and 5
so still a function which accepts a single variable. So now you have two functions which accept a single variable:
sumOfSquares
returnGreatest2 3 5
You can compose them with .
which is what .
is meant for: composing functions with a single variable in and a single variable out.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53324778%2fconfusion-around-when-to-compose-and-when-to-use%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Composition and currying can be a little confusing. sumOfSquares . returnGreatest2
is the same as x -> sumOfSquares (returnGreatest2 x)
, but the type of returnGreatest2 x
is (Ord a, Num a) => a -> a -> (a, a)
. You need to pass all expected arguments before you finally get a value of type (Ord a, Num a) => (a, a)
that is acceptable by sumOfSquares
.
On the other hand, sumOfSquares $ returnGreatest2 3 5 7
is parsed the same as sumOfSquares $ (returnGreatest2 3 5 7)
; the ($)
operator has lower priority than function application (or any other operator, for that matter).
To really compose the two functions, you need several layers of composition:
let f = ((sumOfSquares .) . ) . returnGreatest2
1
I prefer to write the point-free version asfmap (fmap sumOfSquares) . returnGreatest2
. Thefmap
is the same as(.)
here (in the(->) _
functor) but imo is clearer: eachfmap
“maps over” one argument. Including extra parentheses for clarity,fmap (fmap sumOfSquares)
is specialised to the type(a -> a -> (a, a)) -> (a -> a -> a)
, making it composable withreturnGreatest2 :: a -> (a -> a -> (a, a))
.
– Jon Purdy
Nov 17 '18 at 0:43
add a comment |
Composition and currying can be a little confusing. sumOfSquares . returnGreatest2
is the same as x -> sumOfSquares (returnGreatest2 x)
, but the type of returnGreatest2 x
is (Ord a, Num a) => a -> a -> (a, a)
. You need to pass all expected arguments before you finally get a value of type (Ord a, Num a) => (a, a)
that is acceptable by sumOfSquares
.
On the other hand, sumOfSquares $ returnGreatest2 3 5 7
is parsed the same as sumOfSquares $ (returnGreatest2 3 5 7)
; the ($)
operator has lower priority than function application (or any other operator, for that matter).
To really compose the two functions, you need several layers of composition:
let f = ((sumOfSquares .) . ) . returnGreatest2
1
I prefer to write the point-free version asfmap (fmap sumOfSquares) . returnGreatest2
. Thefmap
is the same as(.)
here (in the(->) _
functor) but imo is clearer: eachfmap
“maps over” one argument. Including extra parentheses for clarity,fmap (fmap sumOfSquares)
is specialised to the type(a -> a -> (a, a)) -> (a -> a -> a)
, making it composable withreturnGreatest2 :: a -> (a -> a -> (a, a))
.
– Jon Purdy
Nov 17 '18 at 0:43
add a comment |
Composition and currying can be a little confusing. sumOfSquares . returnGreatest2
is the same as x -> sumOfSquares (returnGreatest2 x)
, but the type of returnGreatest2 x
is (Ord a, Num a) => a -> a -> (a, a)
. You need to pass all expected arguments before you finally get a value of type (Ord a, Num a) => (a, a)
that is acceptable by sumOfSquares
.
On the other hand, sumOfSquares $ returnGreatest2 3 5 7
is parsed the same as sumOfSquares $ (returnGreatest2 3 5 7)
; the ($)
operator has lower priority than function application (or any other operator, for that matter).
To really compose the two functions, you need several layers of composition:
let f = ((sumOfSquares .) . ) . returnGreatest2
Composition and currying can be a little confusing. sumOfSquares . returnGreatest2
is the same as x -> sumOfSquares (returnGreatest2 x)
, but the type of returnGreatest2 x
is (Ord a, Num a) => a -> a -> (a, a)
. You need to pass all expected arguments before you finally get a value of type (Ord a, Num a) => (a, a)
that is acceptable by sumOfSquares
.
On the other hand, sumOfSquares $ returnGreatest2 3 5 7
is parsed the same as sumOfSquares $ (returnGreatest2 3 5 7)
; the ($)
operator has lower priority than function application (or any other operator, for that matter).
To really compose the two functions, you need several layers of composition:
let f = ((sumOfSquares .) . ) . returnGreatest2
edited Nov 15 '18 at 18:27
answered Nov 15 '18 at 17:31
chepnerchepner
264k36254346
264k36254346
1
I prefer to write the point-free version asfmap (fmap sumOfSquares) . returnGreatest2
. Thefmap
is the same as(.)
here (in the(->) _
functor) but imo is clearer: eachfmap
“maps over” one argument. Including extra parentheses for clarity,fmap (fmap sumOfSquares)
is specialised to the type(a -> a -> (a, a)) -> (a -> a -> a)
, making it composable withreturnGreatest2 :: a -> (a -> a -> (a, a))
.
– Jon Purdy
Nov 17 '18 at 0:43
add a comment |
1
I prefer to write the point-free version asfmap (fmap sumOfSquares) . returnGreatest2
. Thefmap
is the same as(.)
here (in the(->) _
functor) but imo is clearer: eachfmap
“maps over” one argument. Including extra parentheses for clarity,fmap (fmap sumOfSquares)
is specialised to the type(a -> a -> (a, a)) -> (a -> a -> a)
, making it composable withreturnGreatest2 :: a -> (a -> a -> (a, a))
.
– Jon Purdy
Nov 17 '18 at 0:43
1
1
I prefer to write the point-free version as
fmap (fmap sumOfSquares) . returnGreatest2
. The fmap
is the same as (.)
here (in the (->) _
functor) but imo is clearer: each fmap
“maps over” one argument. Including extra parentheses for clarity, fmap (fmap sumOfSquares)
is specialised to the type (a -> a -> (a, a)) -> (a -> a -> a)
, making it composable with returnGreatest2 :: a -> (a -> a -> (a, a))
.– Jon Purdy
Nov 17 '18 at 0:43
I prefer to write the point-free version as
fmap (fmap sumOfSquares) . returnGreatest2
. The fmap
is the same as (.)
here (in the (->) _
functor) but imo is clearer: each fmap
“maps over” one argument. Including extra parentheses for clarity, fmap (fmap sumOfSquares)
is specialised to the type (a -> a -> (a, a)) -> (a -> a -> a)
, making it composable with returnGreatest2 :: a -> (a -> a -> (a, a))
.– Jon Purdy
Nov 17 '18 at 0:43
add a comment |
Both sides of (.)
function are expected to be a single argument functions so it treats returnGreatest2
as a a -> (a -> a -> (a, a))
. But sumOfSquares
does not accept (a -> a -> (a, a))
as an argument. One way to do it is to use $
like you did and apply all the arguments, but you can also state first two arguments explicitly:
let x a b = sumOfSquares . returnGreatest2 a b
x :: (Num c, Ord c) => c -> c -> c -> c
this way the types will match.
add a comment |
Both sides of (.)
function are expected to be a single argument functions so it treats returnGreatest2
as a a -> (a -> a -> (a, a))
. But sumOfSquares
does not accept (a -> a -> (a, a))
as an argument. One way to do it is to use $
like you did and apply all the arguments, but you can also state first two arguments explicitly:
let x a b = sumOfSquares . returnGreatest2 a b
x :: (Num c, Ord c) => c -> c -> c -> c
this way the types will match.
add a comment |
Both sides of (.)
function are expected to be a single argument functions so it treats returnGreatest2
as a a -> (a -> a -> (a, a))
. But sumOfSquares
does not accept (a -> a -> (a, a))
as an argument. One way to do it is to use $
like you did and apply all the arguments, but you can also state first two arguments explicitly:
let x a b = sumOfSquares . returnGreatest2 a b
x :: (Num c, Ord c) => c -> c -> c -> c
this way the types will match.
Both sides of (.)
function are expected to be a single argument functions so it treats returnGreatest2
as a a -> (a -> a -> (a, a))
. But sumOfSquares
does not accept (a -> a -> (a, a))
as an argument. One way to do it is to use $
like you did and apply all the arguments, but you can also state first two arguments explicitly:
let x a b = sumOfSquares . returnGreatest2 a b
x :: (Num c, Ord c) => c -> c -> c -> c
this way the types will match.
answered Nov 15 '18 at 17:36
DevNewbDevNewb
741618
741618
add a comment |
add a comment |
You can try this
sumOfSquares . returnGreatest2 3 5 $ 7
$
has te lowest priority. returnGreatest2 3 5
is the function returnGreatest2
partially applied to 3
and 5
so still a function which accepts a single variable. So now you have two functions which accept a single variable:
sumOfSquares
returnGreatest2 3 5
You can compose them with .
which is what .
is meant for: composing functions with a single variable in and a single variable out.
add a comment |
You can try this
sumOfSquares . returnGreatest2 3 5 $ 7
$
has te lowest priority. returnGreatest2 3 5
is the function returnGreatest2
partially applied to 3
and 5
so still a function which accepts a single variable. So now you have two functions which accept a single variable:
sumOfSquares
returnGreatest2 3 5
You can compose them with .
which is what .
is meant for: composing functions with a single variable in and a single variable out.
add a comment |
You can try this
sumOfSquares . returnGreatest2 3 5 $ 7
$
has te lowest priority. returnGreatest2 3 5
is the function returnGreatest2
partially applied to 3
and 5
so still a function which accepts a single variable. So now you have two functions which accept a single variable:
sumOfSquares
returnGreatest2 3 5
You can compose them with .
which is what .
is meant for: composing functions with a single variable in and a single variable out.
You can try this
sumOfSquares . returnGreatest2 3 5 $ 7
$
has te lowest priority. returnGreatest2 3 5
is the function returnGreatest2
partially applied to 3
and 5
so still a function which accepts a single variable. So now you have two functions which accept a single variable:
sumOfSquares
returnGreatest2 3 5
You can compose them with .
which is what .
is meant for: composing functions with a single variable in and a single variable out.
answered Nov 15 '18 at 18:40


Elmex80sElmex80s
2,3271816
2,3271816
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53324778%2fconfusion-around-when-to-compose-and-when-to-use%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
iyPhMccn4sFGiJgyV8xkUD0p9ACJEBXXtWS1,63y ovrlOV76gPs66mDPM0,er
2
I'll give you a hint. What is the type of the composition operator
(.)
?– jkeuhlen
Nov 15 '18 at 17:31
2
Remember that type of
(.) :: (b -> c) -> (a -> b) -> a -> c
. HoweverreturnGreatest2
takes 4 parameters so it shall be applied with 3 parameters (until its type becomesa -> (a,a)
or as in the above type signature(a -> b)
and only then you can apply it to composition operator. Such aslet x = sumOfSquares . returnGreatest 2 3 5
and thenx 7
will give you the result.– Redu
Nov 15 '18 at 17:43
1
Here’s a short derivation of how to convert compositions of multiple arguments like this to point-free form.
x y z -> g ((f x y) z)
=(definition of composition)=x y -> g . f x y
=(rewrite in prefix)=x y -> ((.) g) ((f x) y)
=(definition of composition)=x -> (.) g . f x
=(rewrite in prefix)=x -> ((.) ((.) g)) (f x)
=(definition of composition)=(.) ((.) g) . f
=(instance Functor ((->) a)
)=fmap (fmap g) . f
. Hereg
=sumOfSquares
andf
=returnGreatest2
. In general, to compose a 1-argument function with an n-argument function you need tofmap
n − 1 times.– Jon Purdy
Nov 17 '18 at 2:11