Why does this compile well:
import Network.HTTP.Conduit (simpleHttp)
import qualified Data.ByteString.Lazy.Char8 as L
main = L.putStrLn . L.take 500 =<< simpleHttp "http://stackoverflow.com/"
but this doesn't:
main = L.putStrLn $ L.take 500 =<< simpleHttp "http://stackoverflow.com/"
For me these are exactly the same. The errors in the 2nd case are:
Couldn't match type `L.ByteString' with `m0 b0'
Expected type: L.ByteString -> m0 b0
Actual type: L.ByteString -> L.ByteString
In the return type of a call of `L.take'
In the first argument of `(=<<)', namely `L.take 500'
In the second argument of `($)', namely
`L.take 500 =<< simpleHttp "http://stackoverflow.com/"'
Couldn't match expected type `L.ByteString'
with actual type `m0 b0'
In the second argument of `($)', namely
`L.take 500 =<< simpleHttp "http://stackoverflow.com/"'
(.)
binds stronger than (=<<)
and ($)
binds weaker than (=<<)
. Therefore the first expression can be written as
main = (L.putStrLn . L.take 500) =<< simpleHttp "http://stackoverflow.com/"
and the second as
main = L.putStrLn $ (L.take 500 =<< simpleHttp "http://stackoverflow.com/")
So in the latter expression, the function =<<
, which expects something like a -> m b
as its first argument, is given L.take 500
, which is a function from ByteString
to ByteString
. This doesn't fit together and thats what the error message says.
(.)
and ($)
are never interchangeable, because their types are different:
(.) :: (b->c) -> (a->b) -> (a->c)
($) :: (b->c) -> b -> c
It would have to hold that b ~ (a->b)
and c ~ (a->c)
whereas both are considered as "infinite type", causing an "occurs check" error, e.g. in
Prelude> let g a b = let x = a . b ; y = a $ b in undefined
<interactive>:1:24:
Occurs check: cannot construct the infinite type: a = a1 -> a
....
Even more so in your example when the replacement of one with another causes an entirely different parse of the expression, because of their radically different precedences:
Prelude> :i (.)
(.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in GHC.Base
infixr 9 .
Prelude> :i ($)
($) :: (a -> b) -> a -> b -- Defined in GHC.Base
infixr 0 $
edit: sometimes, in very specific circumstances, .
and $
are interchangeable. Specifically, f $ g $ ... $ h $ x
can be written as f . g . ... . h $ x
.
This is not a contradiction to my opening statement, because
f $ g $ x = f $ (g $ x) = ($) f (($) g x)
whereas
f . g $ x = (f . g) $ x = ($) ((.) f g) x
i.e. ($)
was not replaced with (.)
; rather, the whole expression was rearranged.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With