Reputation: 2967
I'm studying the Writer
monad and have the following:
myFunction :: Int -> Int -> Writer String Int
myFunction e1 e2
| e1 > e2 = do
tell ("E1 greater")
return (e1)
| otherwise = do
tell ("E2 greater")
return (e2)
main = do
-- execWriter :: Writer w a -> w
print $ execWriter . myFunction 1 2
Error:
"Couldn't match type ‘WriterT String Data.Functor.Identity.Identity Int’with ‘a0 -> Writer c0 a1’
Expected type: a0 -> Writer c0 a1
Actual type: Writer String Int"
Why does this computation error with .
and not $
? Perhaps my understanding of function composition is incorrect?
Upvotes: 0
Views: 142
Reputation: 5257
In addition to what Chad said, this happens because regular function application (without using $
) has a higher priority than all operators (infix functions), including .
.
Your example would have worked if you had written it like this:
(execWriter . myFunction 1) 2
Which is equivalent to:
(\x -> execWriter (myFunction 1 x)) 2
Which then evaluates to:
execWriter (myFunction 1 2)
Upvotes: 2
Reputation: 36385
Function composition with .
means that the resulting composition will receive an argument.
This portion:
execWriter . myFunction 1 2
Can be written more explicitly like this:
(\x -> execWriter (myFunction 1 2 x))
Since myFunction
only takes two arguments, you are getting a compile error.
Had you used $
in your code, like this:
execWriter $ myFunction 1 2
The resulting code expanded is equivalent to this:
execWriter (myFunction 1 2)
Which is valid.
Upvotes: 4