F#で行ったすべての進歩について、コンストラクタとデコンストラクタの構文のさまざまな部分でまだ失われています。F#(関数)に(カスタム)型を代入する
私は再帰的シミュレーションを実行しています。パラメータの1つは停止条件の関数です。私は様々な停止条件を選択できます。私はそれらにすべて同じ署名があるようにする。だから私はそれがカスタムタイプにこれらの機能をロックダウンするために、素敵な、教育だろう決める - 署名を一致させるために起こるだけでなく、任意の関数を送ることができるように:
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
私はだと思いますチュートリアルから、型名と同じコンストラクタ名(混乱している...)を持つ、この権利を行うことは、単一のケースの差別化されたユニオンに対してです。しかし、今、私は、実際の関数にこのタイプを適用する方法を見つけ出すことはできません。
let Condition1 lastRet nextRet i fl =
true
私は条件1がタイプStoppingConditionでも作る方法を教えてください。私はそれが簡単だと思う。しかし、私はストップコンディションを、最初と2番目と最後の言葉として、括弧とコロンの有無にかかわらず置いてみました。そしてすべてが誤りです。
ここに忍耐してくれてありがとう。
EDIT:このパターンを模倣しようとすると
:
私はすべての良い(この瞬間のように)4つの回答から傾くものを合成しようとするでしょう
s : string = "abc"
私が書こうとした: Stopping Condition
の
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
let condition1 lastRet nextRet i fl : StoppingCondition = // BAD
//wrong for a type alias, totally wrong for a union constructor
true
//or
let condition1 : StoppingCondition lastRet nextRet i fl = // BAD again
true
または他の挿入(コンストラクタがその行に入るようにプレフィックスを付けようとしています)。
今、私は私がしなければならないでしょうに私がなっていたものを手に入れることを参照してください。
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
let conditionFunc1 lastRet nextRet i fl = //...
true
let stoppingCondition1 = StoppingCondition conditionFunc1
//or
let stoppingCondition2 = StoppingCondition <| (func lastRet nextRet i fl -> false)
//and there's another variation or 2 below
そして、何このアプローチには大きな負のは、労働組合の種類が異なっている方法ですと、私は感謝していませんでした型エイリアス。タイプエイリアスof string
は、宣言されたときに文字列関数を許可します - 実際には文字列であり、 "文字列のもの"を1つのケース識別したユニオンof string
- これは文字列ではありません。 (または、それらの関数のバージョンを文字列関数のラッパーかもしれない)あなたの型に書き出します。)同様に、my関数の型エイリアスはそれらのパラメーターを受け取ります。私の関数のDUは単なるラッパーであり、 。
let x = stoppingCondition1 ret1 ret2 2 3.0 // BAD
//"stoppingCondition1 is not a function and cannot be applied"
を、十分な値は、ラッパーを回避するためにここに私の場合はそこではないですが、タイプの別名が動作します:引数がこれは判別組合では動作しません。
type StoppingAlias = ReturnType -> ReturnType -> int -> float -> bool
let stoppingCondition:StoppingAlias = fun prevRet nextRet i x -> true
let b = stoppingCondition ret1 ret2 10 1.0 // b = true
私はちょうど言ったことがまったくないかもしれないが、私はもっと近いと思う。
編集2:
サイドノート。私の質問は、関数の型を定義することです。そして、それは型エイリアスと共用体型を使って比較されます。私はこれらをしようで働いていたとして、私はまたタイプの別名を使用することについて、このことを学んだ:
type Adder = decimal -> decimal -> decimal
let f1 : Adder = (fun x y -> x + y)
//or
let f2 : decimal -> decimal -> decimal = fun x y -> x + y
が、これらは間違っている::
これは(:https://fsharpforfunandprofit.com/posts/defining-functions/から)作品
let (f2 : Adder) x y = x + y // bad
let (f3 x y) : (decimal -> decimal -> decimal) = x + y // bad
let (f3 : (decimal -> decimal -> decimal)) x y = x + y // bad
F# Type declaration possible ala Haskell?
(また、「タイプを割り当てる」というのは正しいことではありません)
ありがとうございました。私はここで得た4つの有益な答えにはまだ取り組んでいます。私は組合のコンストラクタの理解を真っ直ぐにする必要があり、それはキャスト関数ではないと思う。再度、感謝します。 – RomnieEE
あなたの例では、関数を呼び出すためのパターンで関数をラップしなければならないと、DUを(間違って)使用しようとするときに欠けていたものになります。 (そして、あなたの答えがこの時点で唯一のものではないことを知っています。) – RomnieEE
@RomnieEE喜んで私は助けることができました。 DUの「誤った」使用はまったくありません。そのような単一のケースのタイプは、型の安全性を追加するための完全に正常で意図された方法です。タイプとその唯一のケースに同じ名前を付けることも普通です。型とケースのコンストラクタは全く同じ概念ではないことに注意してください。 (そして、パターンとしてのセマンティクスは、再び異なります。) – Vandroiy