Reputation: 763
Suppose I have data types
data Price = Price Double
data Book = Book {title :: String, bookPrice :: Price}
with a function extracting the numerical price
priceAsDouble :: Price -> Double
priceAsDouble (Price doubleValue) = doubleValue
Now, I want to write an accumulator for a fold over a book list, such as
go :: Double -> Book -> Double
go acc book = acc + priceAsDouble (bookPrice book)
which is fine and compiles.
However, if I change the last line to
go acc book = acc + priceAsDouble $ bookPrice book
I get the following contradicting compiler error:
<interactive>:10:51:
Couldn't match expected type ‘Price -> Double’
with actual type ‘Double’
The first argument of ($) takes one argument,
but its type ‘Double’ has none
In the expression: acc + priceAsDouble $ bookPrice book
In an equation for ‘go’:
go acc book = acc + priceAsDouble $ bookPrice book
<interactive>:10:57:
Couldn't match expected type ‘Double’
with actual type ‘Price -> Double’
Probable cause: ‘priceAsDouble’ is applied to too few arguments
In the second argument of ‘(+)’, namely ‘priceAsDouble’
In the expression: acc + priceAsDouble
Question: I thought that ($) is nothing else but syntactical sugar for parentheses (). Evidently, I was wrong. Where is the mistake in my thought?
Upvotes: 2
Views: 92
Reputation: 42134
$
is syntaxic sugar for parentheses, but it doesn't apply at the level you expect.
go acc book = acc + priceAsDouble $ bookPrice book
is actually interpreted as
go acc book = (acc + priceAsDouble) (bookPrice book)
But acc + priceAsDouble
doesn't make sense as a function to GHC.
Ironically, you'd need more parentheses to make it work:
go acc book = acc + (priceAsDouble $ bookPrice book)
Upvotes: 6