简体   繁体   中英

Confusion about ($) in Haskell: example where ($) does not plainly substitute parentheses

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?

$ 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM