2

タイトルのエラーはあいまいですが、グーグルで検索すると、現在 SO で 2 つのヒットと合計で 5 つのヒットが表示されます (これは珍しい獣であることを示唆しているため、ここにあまり多くの訪問を期待しないでください ;)。この質問はそのリストの6番目になると思います:p。

このスレッドでの Kvb の回答は、エラー テキストが誤解を招きやすく、クロージャー内から base を呼び出すと発生することを示唆していますが、これが機能するため、常にそうであるとは限りません。

// in a closure, but no FS0419
let myObj = fun foo ->
    { new obj() with override this.ToString() = base.ToString() + foo}

しかし、これは失敗します(問題を例示するために私が見つけた最も簡単な方法):

// not in a closure, but raises FS0419
let myObj = 
    { new obj() with override this.ToString() = () |> base.ToString }

継承による型宣言の代わりにオブジェクト式を使用していましたが、カスタム NUnit 制約を作成して新しい FsUnit 制約を作成しようとしました。これは、私が見ていた問題を示す簡略版です。

let EndsWithIgnoreWhitespaceContraint expectedResult = 
    { new EndsWithConstraint(expectedResult) with 
        override __.ApplyTo<'T> (actual: 'T) =
            let actual = box actual
            if actual :? string then 
                actual :?> string
                |> fun s -> if isNull s then String.Empty else s
                |> fun s -> s.Trim()

                // error FS0419: 'base' values may only be used to make direct
                // calls to the base implementations of overridden members
                |> base.ApplyTo 
            else
                exn "String expected .. bla bla..." |> raise        }

// make it available to FsUnit's syntax style (overriding existing endWith)
let endWith = EndsWithIgnoreWhitespaceContraint

// using it:
"  hello world  " |> should endWith "world"

現在、この動作を確認するために FsUnit を知る必要がないことは明らかです。しかし、だまされたことに気付くのに一晩と一日かかりました。実際、SOでこの質問を書いているまで、私はそれを見ませんでした。

これが機能することがわかりました:

x |> base.SomeMethod書く代わりにbase.SomeMethod x

これは驚くべきことです。それがバグか機能かはわかりません。しかし、|>演算子はインライン化されており (別の演算子でテストしました)、新しい関数を作成しないため (同様>>に)、このエラーが発生する理由がわかりません。

実際、 (優先順位のルールなどを除いて) とf aの間に意味的な違いは見当たりません。a |> fでは、なぜエラーが発生するのでしょうか? 私はどのルールを破っていますか?


最後の考えとして、kvb は「baseクロージャーから呼び出すことはできません... カリー化されたメンバーはクロージャーを自動的に作成します」と書いています。

let myObj foo bar = 
    { new obj() with override this.ToString() = base.ToString() + foo + bar}

このエラーの原因と原因を正確に知っている人はいますか?

4

1 に答える 1