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 実装で使用することを意図していますが、任意のモナドで使用できればテストに適していると考えました)

私がそれを書いていたとき、ネストされた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の型とまったく同じでなければならないことがわかりますが、それを尊重する明示的な型を記述する方法がわかりません。 - 別の型宣言で何かを参照する方法はないと思いますが、それは可能ですか?toStringgetenvtoString

4

1 に答える 1

4

を探していると思いますScopedTypeVariables。私はそれを使用したことはありませんが、それは正しいようです。

于 2012-09-21T12:52:09.903 に答える