Оператор Хаскелла - PullRequest
       19

Оператор Хаскелла

14 голосов
/ 14 мая 2010

Я пытаюсь разработать простую функцию усреднения в Haskell. Это похоже на работу:

lst = [1, 3]

x = fromIntegral (sum lst)
y = fromIntegral(length lst)

z = x / y

Но почему не работает следующая версия?

lst = [1, 3]

x = fromIntegral.sum lst
y = fromIntegral.length lst

z = x / y

Ответы [ 3 ]

17 голосов
/ 14 мая 2010

. (состав) имеет более низкий приоритет, чем применение функции, поэтому

fromIntegral.sum lst

интерпретируется как

fromIntegral . (sum lst)

, что неверно, поскольку sum lst не является функцией.

16 голосов
/ 14 мая 2010

Вас сбивают с толку правила приоритетов haskell для операторов, которые сбивают с толку.

Когда вы пишете

x = fromIntegral.sum lst

Хаскелл видит это так же, как:

x = fromIntegral.(sum lst)

Что вы хотели написать было:

x = (fromIntegral.sum) lst
10 голосов
/ 14 мая 2010

Я просто хотел добавить " $ к спасению! ":

x = fromIntegral $ sum lst
y = fromIntegral $ length lst

У него самый низкий приоритет, и он позволяет избежать слишком большого количества скобок. Обратите внимание, что в отличие от (.), Он не выполняет компоновку функции, он оценивает аргумент справа и передает его функции слева. Тип говорит сам за себя:

($) :: (a -> b) -> a -> b
(.) :: (b -> c) -> (a -> b) -> a -> c
...