GHC 说我的函数太笼统而不能作为参数传递。
这是重现错误的简化版本:
data Action m a = SomeAction (m a)
runAction :: Action m a -> m a
runAction (SomeAction ma) = ma
-- Errors in here
actionFile :: (Action IO a -> IO a) -> String -> IO ()
actionFile actionFunc fileName = do
actionFunc $ SomeAction $ readFile fileName
actionFunc $ SomeAction $ putStrLn fileName
main :: IO ()
main =
actionFile runAction "Some Name.txt"
这就是错误所说的:
• Couldn't match type ‘a’ with ‘()’
‘a’ is a rigid type variable bound by
the type signature for:
actionFile :: forall a. (Action IO a -> IO a) -> String -> IO ()
at src/Lib.hs:11:15
Expected type: Action IO a
Actual type: Action IO ()
编译器希望我的类型签名更具体,但我不能,因为我需要将参数函数与不同类型的参数一起使用。就像在我的示例中一样,我将它传递给 anAction IO ()
和 an Action IO String
。
如果我像编译器询问的那样用错误替换调用,(Action IO a -> IO a) -> String -> IO ()
因为它输出一个.(Action IO () -> IO ()) -> String -> IO ()
readFile
IO String
为什么会发生这种情况,我应该怎么做才能将此函数作为参数传递?
我知道如果我只是runAction
在我的actionFile
函数中使用一切都会正常工作,但在我的真实代码runAction
中是一个部分应用的函数,它是从 IO 计算的结果构建的,所以它在编译时不可用。