Haskell "Не аргумент переменной типа в ограничении" - PullRequest
4 голосов
/ 09 июля 2019

Я создал список частично примененных функций в моем 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?

Ответы [ 2 ]

7 голосов
/ 09 июля 2019

Три "закона" операторных секций равны

(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)

и это, согласно eta-сокращению, составляет

($ 4) 
6 голосов
/ 09 июля 2019

Однако я подумал, что из этого следует, что я мог бы написать:

let results = map (4) listOfPartiallyAppliedFunctions

Нет, если бы вы выполнили \x -> 4 x, вы могли бы заменить его на 4,Но поскольку 4 означает, что это экземпляр Num, и вы, вероятно, не сделали функцию a -> b экземпляром Num, компилятор не может решить эту проблему.Таким образом, компилятор говорит, что не находит способа преобразовать число 4 в функцию и определенно не функцию, которая принимает в качестве входных данных функцию Num a => a -> a, а затем преобразует ее в b.

Однако вы можете написать выше:

let results = map <b>($ 4)</b> listOfPartiallyAppliedFunctions

Здесь мы, таким образом, выполняем секцию инфиксного оператора [Haskell-wiki] для ($) :: (a -> b) -> a -> b функция.

...