2016-04-20 9 views
1

いくつかの事が信じられないほどのようだ:なぜこれらのタイプを置き換えることが可能ですか?

foo :: a -> StateT Env (ReaderT Env (ErrorT String IO)) String

は、それが可能であるどのように
foo :: a -> ErrorT String IO String

で置き換えることができますか?結局のところ、彼らは絶対に異なるタイプです...

+1

です。一般に、多型性と過負荷が原因です。 'foo'のコードを見ることなく、正確に言うことはできません。 – Lee

答えて

7

明らかに、すべて状況でこれらを互いに置き換えることはできません。たとえば、ErrorT . return $ Left "Muahar"を明示的に使用する場合は、で、ErrorT String m aでなければなりません。

しかし、両方のタイプはMonadIOMonadError Stringのインスタンスである(トランススタック)モナドMと、フォームa -> M Stringです。そのため、この関数が、liftIO ioactionという形式のアクションのみを使用して定義され、おそらくthrowErrorcatchErrorの場合、これらのモナドのいずれかとして動作します。一般的なタイプは

foo :: (MonadIO m, MonadError String m) => a -> m String 
+2

'foo'から自分の型シグネチャを削除し、ghciで':t foo'を使うと、 'foo'が持つことができる最も一般的な型を見ることができます。また、 ':i SomeFunctionOrTypeOrTypeClass'は、モナドスタックを計算するときに非常に便利です。 –

+1

これは実際には_used_であると思われるコードの型シグネチャを省略するよう招待されてはいけません。 – leftaroundabout

+0

また、ghciで示される推定型が実際には最も有用なものではない場合や、 'smoothInterpolate ::(Data.LinearMap.HerMetric.HasMetric 'y、 Data.LinearMap.HerMetric.HasMetric' (Data.LinearMap.HerMetric.DualSpace y) '...(より多くの制約)...' Data.LinearMap.HerMetric.DualSpace (Data.LinearMap.HerMetric.DualSpace y) 〜y、スカラー(必要に応じて) 〜マニホールド0.2.1.0:Data.Manifold.Types.Primitive.ℝ)=> Data.List.NonEmpty.NonEmpty(x、y) - > x - > y'? – leftaroundabout

関連する問題