我一直在处理隐式参数,有时我觉得这些参数很有用,但我试图做一些类似下面代码的事情(不编译)
{-# LANGUAGE ImplicitParams #-}
main = print (f z)
f g =
let
?x = 42
?y = 5
in
g
z :: (?x :: Int) => Int
z = ?x
我想要的基本上是一个函数f
,它运行一个带有"上下文"的给定函数。在上面的情况下,f z
将使用?x = 42
运行z
,在这种情况下,它自然只返回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
构造函数中提取适当的隐式参数的函数相对来说是微不足道的,但我想应用一个具有这些隐式参数。
类似这种方法(编译)会很好,或者另一种方法也可以,它可以让我轻松地为各种函数设置隐式参数上下文。
您需要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