Функция, которая устанавливает неявный контекст параметров

Я возился с неявными параметрами, которые я иногда находил полезными, но пытался сделать что-то вроде кода ниже (который не компилируется)

{-# LANGUAGE ImplicitParams #-}

main = print (f z)

f g =
  let 
    ?x = 42
    ?y = 5
  in
    g

z :: (?x :: Int) => Int
z = ?x

То, что я хочу в основном это функция f который выполняет данную функцию с "контекстом". В случае выше, f z побежит z с ?x = 42который, естественно, просто возвращается 42 в этом случае и, следовательно, эта программа должна напечатать 42, Но я получаю ошибку:

• Unbound implicit parameter ?x::Int arising from a use of ‘z’
• In the first argument of ‘f’, namely ‘z’
  In the first argument of ‘print’, namely ‘(f z)’
  In the expression: print (f z)

Это потому, что нет контекста для z где он впервые используется в main, даже если f предоставляет контекст.

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

Что-то вроде этого подхода (который компилируется) было бы хорошо, или альтернативно другой подход, который позволяет мне легко устанавливать контекст неявного параметра для множества функций, также был бы хорош.

1 ответ

Решение

Вам нужна явная аннотация типа для f, GHC не может вывести правильный тип.

{-# LANGUAGE ImplicitParams, Rank2Types #-}

main = print (f z)

f :: ((?x :: Int, ?y :: Int) => a) -> a
f g =
  let 
    ?x = 42
    ?y = 5
  in
    g

z :: (?x :: Int) => Int
z = ?x
Другие вопросы по тегам