2

Purescript で Reader モナドをいじっていたところ、奇妙な動作に遭遇しました。このモナドを理解していないからなのか、それとも他の何かが欠けているからなのかはわかりません。

これは私のコードです:

type Level = Number
type Doc = Reader Level String

renderLine :: String -> Level -> String
renderLine s 0 = s
renderLine s l = "\t" ++ (renderLine s (l - 1))

line :: String -> Doc
line s = do
    level <- ask
    return (renderLine s level)

これは問題なく、コンパイルされます。それにもかかわらず、これの前に、次のような関数行でより簡単なことを試しました:

line :: String -> Doc
line s = do
    level <- ask
    return "Hello Reader monad"

(renderLine s level) と "Hello Reader モナド" が同じ型であるにも関わらず、コンパイルされません。このエラーがスローされます:「Control.Monad.Reader.Class.MonadReader u14555(Control.Monad.Reader.Trans.ReaderT Prim.Number Control.Monad.Identity.Identity)のインスタンスが見つかりません」

私は何かが欠けていると確信していますが、何がわかりません。

4

1 に答える 1

7

そのエラーのより読みやすいバージョンは次のようになります。

No instance found for MonadReader ? (Reader Number)

ここでの問題は、PureScript の機能依存関係の欠如によるものだと思います。Haskell では、クラスはによって決定されるようMonadReaderに定義されていますが、PureScript ではそれができません。MonadReader r m | m -> rrm

後者ではなく前者の場合に機能する理由は、 の呼び出しで の型がlevelと統一されているためだと思います。LevelrenderLinerLevel

後者の場合は何もしていないのでlevel、型変数は統一されていないままであり、それがエラーの原因です。実際には MonadReader のインスタンスrが不明な場合です。

于 2015-03-17T14:54:45.883 に答える