我在考虑Haskell(GHC)中的隐式参数时遇到了问题。我有一个函数 f ,它假定隐式参数 x ,并希望通过将 f 应用于来将其封装在上下文中克
f :: (?x :: Int) => Int -> Int
f n = n + ?x
g :: (Int -> Int) -> (Int -> Int)
g t = let ?x = 5 in t
但是当我尝试评估时
g f 10
我收到 x 未绑定的错误,例如:
Unbound implicit parameter (?x::Int)
arising from a use of `f'
In the first argument of `g', namely `f'
In the second argument of `($)', namely `g f 10'
有谁能告诉我,我做错了什么?
(我试图让Haskell的WordNet接口工作 - http://www.umiacs.umd.edu/~hal/HWordNet/ - 它以上述方式使用隐式参数,当我尝试编译它时,我不断收到上面的错误)
答案 0 :(得分:6)
g
的第一个参数必须是((?x::Int) => Int -> Int)
类型,以澄清?x应该传递给f
。这可能是启用Rank2Types(或RankNTypes)。不幸的是,GHC无法推断出这种类型。
{-# LANGUAGE ImplicitParams #-}
{-# LANGUAGE Rank2Types #-}
f :: (?x::Int) => Int -> Int
f n = n + ?x
g :: ((?x::Int) => Int -> Int) -> (Int -> Int)
g f = let ?x = 5 in f`
现在g f 10
有效。
答案 1 :(得分:5)
这里的问题是?x
在被引用的点上没有约束。您和我可以看到?x
将绑定在g
中,但编译器不能。一个(令人困惑的)解决方案是改变
g f 10
到
g (let ?x = 5 in f) 10
答案 2 :(得分:2)
此代码工作正常,但请确保您实际启用了隐式参数的扩展名!
例如,在.hs文件的顶部,您应该包含:
{-# LANGUAGE ImplicitParams #-}
或者,每次运行GHC时都可以使用-XImplicitParams
标志。
dyn-40-155:Test tommd$ cat so.hs
{-# LANGUAGE ImplicitParams #-}
f :: (?x :: Int) => Int -> Int
f n = n + ?x
g :: (Int -> Int) -> (Int -> Int)
g t = let ?x = 5 in t
dyn-40-155:Test tommd$ ghci so.hs
GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-simple ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main ( so.hs, interpreted )
Ok, modules loaded: Main.
*Main> g (*3) 4
12
如果这不起作用,那么我怀疑你的GHC安装不好。