问题
I try to develop a simple average function in Haskell. This seems to work:
lst = [1, 3]
x = fromIntegral (sum lst)
y = fromIntegral(length lst)
z = x / y
But why doesn't the following version work?
lst = [1, 3]
x = fromIntegral.sum lst
y = fromIntegral.length lst
z = x / y
回答1:
You're getting tripped up by haskell's precedence rules for operators, which are confusing.
When you write
x = fromIntegral.sum lst
Haskell sees that as the same as:
x = fromIntegral.(sum lst)
What you meant to write was:
x = (fromIntegral.sum) lst
回答2:
.
(composition) has a lower precedence than function application, so
fromIntegral.sum lst
is interpreted as
fromIntegral . (sum lst)
which is wrong since sum lst
is not a function.
回答3:
I just wanted to add "$ to the rescue!":
x = fromIntegral $ sum lst
y = fromIntegral $ length lst
It has the lowest precedence and it's there to avoid too many parenthesis levels. Note that unlike (.), it doesn't do function composition, it evaluates the argument to the right and pass it to the function on the left. The type says it all:
($) :: (a -> b) -> a -> b
(.) :: (b -> c) -> (a -> b) -> a -> c
来源:https://stackoverflow.com/questions/2834626/haskell-dot-operator