在原始代码中可以看到我只是将一个表达式提取到一个绑定中,这是 haskell 声称应该始终可能的基本内容之一。
最小案例(在 freenode 上 @dminuoso 的帮助下创建)
我想g
保持多态性(这样我就可以将它提供给其他期望它的函数):
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
main = do
let a :: forall t. Functor t => t () = undefined
let g :: forall u. Functor u => u () = a
pure ()
错误:
source_file.hs:6:44:
Couldn't match expected type ‘forall (u :: * -> *).
Functor u =>
u ()’
with actual type ‘t0 ()’
When checking that: t0 ()
is more polymorphic than: forall (u :: * -> *). Functor u => u ()
In the expression: a
#haskell IRC 上发布的原始问题(动机):
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
class Monad m => Monad' m where
instance Monad' IO where
f1 :: (forall m . Monad' m => m Int) -> IO Int
f1 g = do
let a :: forall n . Monad' n => n Int = g
a
-- this works
--f1 :: (forall m . Monad' m => m Int) -> IO Int
--f1 g = do
-- g
main = print $ "Hello, world!"
但我得到:
source_file.hs:12:45:
Couldn't match expected type ‘forall (n :: * -> *).
Monad' n =>
n Int’
with actual type ‘m0 Int’
When checking that: m0 Int
is more polymorphic than: forall (n :: * -> *). Monad' n => n Int
In the expression: g
基于https://ghc.haskell.org/trac/ghc/ticket/12587我尝试显式应用类型来帮助类型检查器:
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
class Monad m => Monad' m where
instance Monad' IO where
f1 :: (forall m . Monad' m => m Int) -> IO Int
f1 g = do
let a :: forall n . Monad' n => n Int = g @n
a
main = print $ "Hello, world!"
但后来我得到:
main.hs:13:48: error: Not in scope: type variable ‘n’