4

我有以下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尊重- 我不认为有任何方法可以引用不同类型声明中的任何内容,甚至可以做到吗?

4

1 回答 1

4

我想你正在寻找ScopedTypeVariables. 我从来没有用过,但它看起来不错。

于 2012-09-21T12:52:09.903 回答