2010-06-26 2 views
2

Этот вопрос относится к этому Function Composition VS Function Application, на который ответил antal s-z.Ошибка типа Haskell от функции Применение к функциональному составу

Как вы можете это получить?

map has type (a -> b) -> [a] -> [b] 
head has type [a] -> a 
map head has type [[a]] -> [a] 

Почему следующий код имеет ошибку типа для композиции функции?

test :: [Char] -> Bool 
test xs = not . null xs 

getMiddleInitials :: [String] -> [Char] 
getMiddleInitials middleNames = map head . filter (\mn -> not . null mn) middleNames 

, но это не ошибка типа

getFirstElements :: [[a]] -> [a] 
getFirstElements = map head . filter (not . null) 

ли это необходимо, чтобы написать свободную функцию точки для того, чтобы использовать функцию композиции? Я все еще не очень понимаю, как работает функция композиции.

Пожалуйста, помогите. Спасибо.

ответ

3

Ваша ошибка здесь на самом деле очень просто. Если вы помните последнюю часть my answer to your last question, оператор . имеет более высокий приоритет, чем ничего кроме для применения функции. Итак, рассмотрим ваш пример

test :: [Char] -> Bool 
test xs = not . null xs 

Это обрабатывается как test xs = not . (null xs). Конечно, null xs имеет тип Bool, и вы не можете составить логическое значение, и поэтому вы получите ошибку типа. Таким образом, вы могли бы сделать ваши примеры работают так:

test :: [Char] -> Bool 
test xs = (not . null) xs 

getMiddleInitials :: [String] -> [Char] 
getMiddleInitials middleNames = 
    (map head . filter (\mn -> (not . null) mn)) middleNames 

Конечно, писать это так необычно, но это будет работать нормально.

И нет, есть другие виды использования функциональной композиции, кроме точечного стиля. Одним из примеров является использование композиции функций для некоторых вещей (, например аргумент map или filter), но укажите остальные. Например, возьмем этот надуманный пример:

rejectMapping :: (a -> Bool) -> (a -> b) -> [a] -> [b] 
rejectMapping p f = map f . filter (not . p) 

Это отчасти точка свободной (not . p, к примеру, и мы остановились в последний аргумент), но частично точечными полностью (о существовании p и f).

+0

Не совсем понимаю последнюю часть, которая отвергает пример с образцом. – peterwkc

+0

Какую часть этого вы не понимаете? Мотивация за ней, что она должна делать или как она работает? Он использует только то, что вы уже видели, поэтому, если вы думаете об этом, вы сможете следовать ему! –

4

Это только потому, что применение функции x y имеет более высокий приоритет, чем состав x . y

test :: [Char] -> Bool 
test xs = (not . null) xs 
-- # ^  ^

getMiddleInitials :: [String] -> [Char] 
getMiddleInitials middleNames = (map head . filter (\mn -> (not . null) mn)) middleNames 
-- #       ^      ^  ^^
Смежные вопросы