2017-02-15 4 views
1

В чем разница междуHaskell значения функции возврата

dotEx1 = map(+3) . filter (>100) 

и

dotEx1 xs = map(+3) . filter (>100) xs 

так

myFilter xs = filter (>100) xs 

и

myFilter = filter (>100) 

такие же, почему не

dotEx1 = map(+3) . filter (>100) 

и

dotEx1 xs = map(+3) . filter (>100) xs 

то же самое?

+0

Из-за оператора точки? –

+1

Я чувствую, что существующие ответы на самом деле не касаются вашего вопроса: они говорят «как это исправить», но не «почему это неправильно». Ответ одного предложения на эту часть довольно прост: функциональное приложение имеет более высокий приоритет, чем любой инфиксный оператор, включая '(.)'. (На самом деле я не думаю, что это одно предложение добавляет достаточно ценности, чтобы гарантировать еще один ответ). –

ответ

7

. функция определяется следующим образом:

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

Функция состоит из оператора . должен принимать аргумент. Поэтому

dotEx1 = map(+3) . filter (>100) 

То же самое, как оператор

dotEx1 xs = (map(+3) . filter (>100)) xs 
4

дот имеет подпись:

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

здесь используется оператор инфикс. Так, в своем первом заявлении вы на самом деле написано:

dotEx1 = (.) (map (+3)) (filter (>100)) 

И это имеет смысл, так как filter (>100) имеет подпись: (Num n,Ord n) => [n] -> [n] и map (+3) имеет подпись Num n => [n] -> [n]. Однако, если вы пишете:

dotEx1 xs = (.) (map (+3)) (filter (>100) xs) 

затем filter (>100) xs имеет подпись (Num n,Ord n) => [n] и поэтому это значение (не функция, или, возможно, функция без аргументов). Таким образом, оператор точки не может использоваться (типы не совпадают).

неформально оператор точка должна быть предоставлена ​​две функции f и g и генерирует функцию, где f применяется послеg применяется на входе. Но g, таким образом, должна быть функцией, принимающей один аргумент.

3

Оператор точек имеет низкий приоритет, потому что вы хотите частично применять функции.То есть,

map (+3) . filter (>100) 

читается как

(map (+3)) . (filter (>100)) 

В расширительном вы получите

dotEx1 xs = (map (+3)) . (filter (>100) xs) 

вместо

dotEx1 xs = (map (+3) . filter (>100)) xs 

Более читаемый вариант, который также работает:

dotEx1 xs = map (+3) . filter (>100) $ xs 
Смежные вопросы