Я создал список частично примененных функций в моем REPL следующим образом:
listOfPartiallyAppliedFunctions = map (*) [1..100]
Затем я хотел бы создать список результатов завершения приложения функции, что я могу легко сделать, предоставив лямбда-функция карты следующим образом:
let results = map (\x -> x 4) listOfPartiallyAppliedFunctions
Что в основном означает сопоставление примененной функции x с 4 по списку частично примененных функций, где x — каждая частично примененная функция из списка.
Однако я подумал, что из этого следует, что я мог бы написать:
let results = map (4) listOfPartiallyAppliedFunctions
Поскольку не должно быть необходимости предоставлять лямбду для функции карты, поскольку она должна знать, что нужно применить 4 к частично примененным функциям, содержащимся в listOfPartiallyAppliedFunctions.
Однако я получаю эту ошибку:
• Non type-variable argument in the constraint: Num ((a -> a) -> b)
(Use FlexibleContexts to permit this)
• When checking the inferred type
it :: forall a b. (Num a, Num ((a -> a) -> b), Enum a) => [b]
Может ли кто-нибудь помочь мне разобрать эту ошибку? Я думал, что 4 был экземпляром конструктора типа Num?





However, I thought it would then follow that I could write:
let results = map (4) listOfPartiallyAppliedFunctions
Нет, если бы вы исполнили \x -> 4 x, вы могли бы заменить его на 4. Но поскольку 4 означает, что это экземпляр Num, и вы, вероятно, не сделали функцию a -> b экземпляром Num, компилятор не может решить эту проблему. Таким образом, компилятор говорит, что он не находит способа преобразовать число 4 в функцию, и уж точно не в функцию, которая принимает на вход функцию Num a => a -> a, а затем преобразует ее в b.
Однако вы можете написать приведенное выше просто:
let results = map ($ 4) listOfPartiallyAppliedFunctionsТаким образом, здесь мы выполняем разделение инфиксного оператора [Haskell-wiki] для функции ($) :: (a -> b) -> a -> b.
А, это оператор приложения инфиксной функции? Я видел это повсюду, но никогда не понимал этого, так что это все равно, что сказать: «Применить функцию (то есть текущий элемент в моем списке частично примененных функций, которые я отображаю) к значению 4?
@ThomasCook: разделение инфиксного оператора указывает, что ($ 4) эквивалентно \x -> ($) x 4, поскольку ($) реализовано как ($) f x = f x, таким образом, оно эквивалентно \x -> x 4
Три «закона» операторных секций являются
(a `op` b) = (a `op`) b = (`op` b) a = op a b
(отсутствующий аргумент помещается в свободный слот рядом с оператором),
или с $,
a b = (a $ b) = (a $) b = ($ b) a = ($) a b
Таким образом
(\ x -> x 4) = (\ x -> x $ 4) = (\ x -> ($ 4) x)
и это, путем эта-редукции,
($ 4)
Фантастический ответ, как всегда, Виллем - ценю это!