如何为此子功能提供显式类型?

时间:2012-09-21 12:46:52

标签: haskell types typeclass

我有以下haskell代码来扩展字符串中的环境变量(解析代码省略):

import Control.Monad (liftM)

data Token = Literal String | EnvReference String deriving Show

expandTokens :: (Monad m) => (String -> m (Maybe String)) -> [Token] -> m String
expandTokens getEnv toks = liftM concat (mapM toString toks) where
    toString (Literal s) = return s
    toString (EnvReference v) = liftM (maybe "" id) (getEnv v)

(它打算与getEnv的IO实现一起使用,但我认为如果可以与任何monad一起使用它会更好)

当我编写它时,我试图给嵌套的toString函数一个明确的类型:

toString :: Monad m => Token -> m String

但是ghc说:

Sample.hs:8:58:
    Could not deduce (m ~ m1)
    from the context (Monad m)
      bound by the type signature for
                 expandTokens :: Monad m =>
                                 (String -> m (Maybe String)) -> [Token] -> m String
( ... )

我得知,expandTokens中的“Monad m”必须与m的类型toString完全相同(因为它引用了包含函数的getenv) ,但我无法弄清楚如何为toString编写一个尊重它的显式类型 - 我认为没有办法在不同的类型声明中引用任何东西,它甚至可以完成吗?

1 个答案:

答案 0 :(得分:4)

我认为你正在寻找ScopedTypeVariables。我从来没有用过它,但它看起来是正确的。