2011-12-31 7 views
1

Я писал быстрый однострочный в GHCi и пытался составить сумму с картой. Я понял причину, по которой это не удалось, потому что карта дает вывод общего типа [b], тогда как сумма принимает определенный вход Num a => [a]. Однако в этом коде нет ничего плохого, предполагая, что вывод функции отображения - тип Num b => [b].Haskell: Создать функцию определенного типа с одним типом общего типа?

Я думал писать объявление типа ограничивающего может работать (хотя я думаю, что мешает вам делать это в GHCi), но она до сих пор не сделала:

myFunc :: Num b => (a -> b) -> [a] -> b 
myFunc = sum . map 

Дал мне следующую ошибку:

Couldn't match expected type `[[a] -> b]' 
      with actual type `[a] -> [b]' 
Expected type: (a -> b) -> [[a] -> b] 
    Actual type: (a -> b) -> [a] -> [b] 
In the second argument of `(.)', namely `map' 
In the expression: sum . map 

Есть ли способ сделать это? Может быть, я просто упустил что-то очевидное (новое для Haskell).

+2

Попробуйте 'myFunc f = sum. карта f'. '(.)' составляет «унарные» функции. –

ответ

5

sum . map не является определением, которое вы ищите. Заметим, что

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

Оператор точка принимает два одинарные функции. Она не работает, как map принимает два аргумента:

map :: (a -> b) -> [a] -> [b] 

Одним из возможных решений было бы явно связать map «s первый аргумент:

myFunc :: Num c => (a -> c) -> [a] -> c 
myFucc f = sum . map f 

В качестве альтернативы можно использовать curry и uncurry и достижения такой же результат.

myFunc = curry $ sum . uncurry map 
+3

Другое определение без точек: '(sum.). map' или 'sum.: map' где' (. :) = (.). (.) '. –

+1

«Оператор точки принимает две унарные функции. Он не работает ...» Ну, все функции являются технически унарными функциями; Функции с несколькими аргументами - это только унарные функции, возвращающие другие функции. Поэтому он не «не работает», потому что карта принимает два аргумента; он работает только иначе, чем – newacct

Смежные вопросы