这取决于您尝试在 A 中存储的内容。
如果您尝试存储任何类似的函数,只要 m 是 Monad,将其用作类型参数,并在您的函数中指定此约束:
newtype A m = A { _run :: A m -> [Int] -> m Int }
myFunction :: Monad m => A m -> A m
然后,您可以在构造函数中包含 A [] -> [Int] -> [Int] 或 A Maybe -> [Int] -> Maybe Int 之类的内容。
f :: A Maybe -> [Int] -> Maybe Int
f _ (x:_) = Just x
f _ [] = Nothing
g :: Monad m => A m -> [Int] -> m Int
g _ xs = return $ head xs
myA :: A Maybe
myA = A f -- this works
myOtherA :: Monad m => A m
myOtherA = A g -- this works too
另一方面,如果你想强制你存储的数据是多态的,你可以使用GHC扩展RankNTypes。
{-# LANGUAGE RankNTypes #-}
newtype A = A { _run :: forall m. Monad m => A -> [Int] -> m Int }
myFunction :: A -> A
你不能在构造函数中包含 A -> [Int] -> [Int] 或 A -> [Int] -> Maybe Int 之类的东西,因为 forall 强制它们比 any Monad m 通用,所以它必须是类型为Monad m => A -> [Int] -> Maybe Int。
f :: A -> [Int] -> Maybe Int
f _ (x:_) = Just x
f _ [] = Nothing
g :: Monad m => A -> [Int] -> m Int
g _ xs = return $ head xs
myA :: A
myA = A f -- this does not work ; it wants forall m. Monad m => m, not []
myOtherA :: A
myOtherA = A g -- this does work
仅当您打算为 A 值使用不同的特定 Monad 实例时,这才会真正有用。例如,镜头就是这样工作的,它使用不同的函子对镜头做不同的事情。