设置隐式参数上下文的函数

A function that sets an implicit parameter context

我一直在研究隐式参数,有时我发现这些参数很有用,但我试图做一些类似于下面的代码(无法编译)

{-# LANGUAGE ImplicitParams #-}

main = print (f z)

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

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

我想要的基本上是一个函数 f,其中 运行 是一个带有 "context" 的给定函数。在上面的例子中,f z 将 运行 z?x = 42,在这种情况下自然只是 returns 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)

这是因为 zmain 中首次使用时没有上下文,即使 f 提供了上下文。

我尝试这样做的原因是因为我有许多使用隐式参数的函数,以及一个 GADT 具有不同但相似的实现选项。编写一个从每个可能的 GADT 构造函数中提取适当的隐式参数的函数相对简单,但是我想应用具有这些隐式参数的函数。

像这种(可以编译的)方法会很好,或者允许我轻松地为各种函数设置隐式参数上下文的不同方法也很好。

您需要 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