質問を苦境。明示的な型署名なしでこのコードを動作させる方法はありますか?GHCの型推論は
コード。まず、Data.Newtype
に触発された、実際にはもっと良い方法の代替MonadTrans
クラスがあります。それは、このようになります
{-# LANGUAGE FlexibleContexts, TypeFamilies #-}
module Alt.Control.Monad.Trans where
import Control.Monad
class (Monad , Monad (BaseMonad)) => MonadTrans (:: * -> *) where
type BaseMonad :: * -> *
lift :: (BaseMonad) α -> α
はその後、私はこの方法foo
でクラスA
を持っている、といくつかの基本モナドM
がA
であれば、任意の変換モナドT M
もA
です。コードでは、私は今、置換、最初の引数でfoo
のショートカットを作成したい場合は
class A where
foo :: String -> ()
instance (A (BaseMonad), MonadTrans) => A where
foo n = lift $ foo n
はしかし、その後、私は明示的な型シグネチャを必要とする、またはコンパイラのコンテキストスタックがオーバーフローします。
minimize_call :: A => ()
minimize_call = foo "minimize"
可能な情報推論を支援します。たとえば、関連するタイプがB :: * -> *
であるとします。私はコンパイラにB
がB t /= t
、B (B t) /= B t
などを満たすようにしたいと思っています。すなわち、B
は何らかの形で単調です - 関連する型を追跡することはnewtypeラッパーを取り除くことと同等で、newtypeラッパーを永遠に削除することはできませんしたがって、署名に文脈A
を追加する必要があります。
申し訳ありませんが、代替のMonadTransに切り替えたのを覚えていないと気になりませんでした...今は、よりクリーンなコードが作成されていますが、もっと重要な理由があったと思います。 – gatoatigrado
興味深い質問。なぜあなたは明示的な型署名をしたくないのですか? 'minimize_call'はポリモーフィックな定数ではなく、固定値でなければなりません(多分多態性になるかもしれませんが、わかりません)?それはいくつかの単一の固定タイプを持っている場合、私はむしろそれを文書化し、そうでなければ、私はむしろ** **を**文書化したいと思います。読者に、プログラムの全体分析を強制的に行わせて、 'minimize_call'のタイプが少し生産的でないように見えるようにします。 – Ben
@Benこの場合、 'minimize_call'の型シグネチャを持つことは良い方法です。しかし、タイプ推論が壊れていると、何かが間違っている(コンパイラー、デザイン、コンパイラー、またはコンパイラーとの通信に問題がある)ことがわかり、問題を引き起こす可能性があります。 – gatoatigrado