2016-12-31 9 views
1

私はthis F# wikibookを使っていますが、リンクされたページの関数の構成セクションに表示されているものに混乱しています。私が思い付くことができF#関数の構成が基本関数の型を変更しました

最も簡単な例は次のとおりです。

// int -> int 
let f x = x + x 
// float -> float 
let g x = x + 1.0 

これで結構です。私はこれらの関数の型を簡単に理解し、fsiでそれらを実行し、上記で取り上げた型の値を受け取り、返すことを確認できます。

私は次の行を追加すると、私は理解していない変更を参照してください。

// equivalent to f (g x) 
let fog = f << g 

私がこれを理解する方法では、fはintを期待しているので動作しませんが、gはfloatを返します。

このコンポジションをfsiで定義すると、予想されるタイプのエラーが発生します。これらをすべて.fsxファイルに入れてfsiにすべて送ると、fの署名はfloat - > floatになります。起こっ型推論の

  • 範囲:

    は、私は次のように混乱していますか?

  • これらをファイルとfsiで定義することの違いは何ですか?

私は検索しようとしましたが、この時点でこれらの質問に対する回答を効果的に見つけることができません。あなたがRTFMに対処する部分を教えてくれるなら、私はRTFMに満足しています。

+2

あなたの前提は正しいです。それは常に失敗するでしょう。私はそれをファイルに保存することで、あなたが言ったシナリオを再現することはできません。それを行うだけで、 '' float-> float''を推測することはできません。間違った方法でテストしているかもしれません。再度確認してください。 – Gustavo

+1

申し訳ありませんが、私は私の例を間違えて更新しました。 fの定義に1があってはなりません。合成ステップがなければ、fは以下のように定義するとint - > intになります。合成関数では、float - > floatです。 let f x = x + x – greggyb

+1

OK、今質問に答えることができます;) – Gustavo

答えて

6

(+)演算子は汎用型ですが、デフォルトタイプはintなので、コンパイルするコードの残りの部分に応じて、デフォルトの型は適用されません。

これ

はつまり、あなたは、型推論を与えた場合にのみ、この:

let f x = x + x 

それは、intと推測されますが、それは(+)演算子をサポートする他の数値型だったかもしれないが、あなたにはより多くの情報を与えなかったので、デフォルトを使用します。

F#は、.NETタイプのシステムでエンコードするために、この関数のタイプを選択する必要があります。ただし、定義する場合を除き、inlineをそのまま使用してください。あなたが機能fを使用するラインと共に追加のコードをコンパイルする場合

let inline f x = x + x 

// val inline f : x: ^a -> ^b when ^a : (static member (+) : ^a * ^a -> ^b) 

さて、型推論は、タイプを分析し、より正確な候補を得ることができます。ここで

は単純な例です、新しいスクリプトを開いて、このコードを貼り付けます。今、各ラインで+ 'CTRLを押して、行単位でそれを実行

let f x = x + x 
let v = f 1. 

、それはintを推測し、上の失敗します2行目。

しかし、今は全体のスクリプトを選択し、+ ENTER​​を押すと、それがコンパイルされ、fを使用して次の行の情報を利用することができたので、ffloatと推測されます。

+0

ありがとうございます。このタイプの推論がどのように起こるかについて私が行うことができるさらなる読書に向けて私を指摘できますか? – greggyb

+1

このブログではあなたが投稿した同じ例を挙げています:http://withouttheloop.com/articles/2014-10-21-fsharp-adhoc-polymorphism/ – Gustavo

+1

[F#4.0 spec]のセクション1.1.3(http: //fsharp.org/specs/language-spec/4.0/FSharpSpec-4.0-latest.pdf) – Gustavo

関連する問題