2016-03-25 5 views
1

F#の新しい2時間ですが、またはTimeSpanのいずれかの差別化された結合型を宣言する方法を考えています。C#のためのFuncとTimeSpanの区別された連合

namespace Test 

open System 

type FuncOrTimeSpan = 
    // Should this be written in a different way to be able to take fun (a, b, c) -> ...? 
    | Func of Func<DateTime, DateTime, Option<DateTime>, Option<DateTime>> 
    | TimeSpan of TimeSpan 

module ThingDoer 

    let (|ActiveThing|_|) input = Option.Some(1) 

    // Do I need to tell this function that I expect it to return FuncOrTimeSpan? 
    let ReturnEitherFuncOrTimeSpan input = 
    match input with 
    | "should return TimeSpan" -> FuncOrTimeSpan.TimeSpan(TimeSpan.FromSeconds(10)) 
    | ActiveThing number -> FuncOrTimeSpan.Func(fun (a, b, c) -> Option.Some(DateTime.Now)) 

私はのために怒鳴ら取得しています:この関数は、あまりにも多くの引数を取るか、機能が期待されていないコンテキストで使用されています。

ラムダをFuncOrTimeSpan.Funcに渡せるようにするにはどうすればよいですか?

また、Func of Func<DateTime, DateTime, Option<DateTime>Func of DateTime -> DateTime -> Option<DateTime> -> Option<DateTime>のように書き換える必要がありますか?私はこれが何を意味するのか分かりませんし、試してみると助けになりませんでした。

私はおそらくC#からこの関数とのインタフェースを考えているはずです(しかし、それとインタフェースする必要があるC#部分もF#に書き直されるため、interopを破るソリューションはまだ歓迎です)。

+0

ActiveThingで何をしようとしていますか? –

+0

'ActiveThing'は大丈夫です。それはmatch節のアクティブなパターンです。問題はありません。私は名前を思い出すことができなかったし、私がそれについて読むタブを見つけることができなかったので、それを 'ActiveThing'と呼んだ。私も間違って書き直しました、今編集されています。 –

+0

@TomášHübelbauer部分的なアクティブパターンの構文が正しくないため、そこに問題があります。 https://msdn.microsoft.com/en-us/library/dd233248.aspx#Anchor_2を参照してください。 – TheInnerLight

答えて

3

それはまさにあなたの意図は、あなたが解決しようとしている問題の定性的な記述がそうであるものを知らなくても、この質問に答えることは非常に難しいのカレー結果を変換する必要があります明確な答えを与えるのに役立つ、私は最善を尽くします。

まず第一に、あなたのタイプの定義は次のようになります。

type FuncOrTimeSpan = 
    | Func of (DateTime -> DateTime -> Option<DateTime> -> Option<DateTime>) 
    | TimeSpan of TimeSpan 

私はあなたの現在の型定義に何か問題が表示されていないが、それはSystem.Funcを使用してのF#関数を記述することは非常に珍しいです。

あなたの代わりにカリー引数の、あなたはこのようにそれを書きたいtupledたい場合:

type FuncOrTimeSpan = 
    | Func of (DateTime * DateTime * Option<DateTime> -> Option<DateTime>) 
    | TimeSpan of TimeSpan 

あなたがが学習している間あなたは違いを考え出したまで、私はあなたが最初にこだわるお勧めします。基本的には、カドライドされた引数は便利な部分的な適用を可能にし、タプルされた引数はパラメータ/リターンの便利なグループ化を可能にします。 F#でのカリングの詳細については、https://fsharpforfunandprofit.com/posts/currying/を参照してください。

とにかく、最初の型定義で今後、あなたの関数は次のようになります。それは行いませんので、あなたがこのActiveThing部分アクティブパターンを使用したい理由を私は知らない

let returnEitherFuncOrTimeSpan input = 
    match input with 
    | "should return TimeSpan" -> TimeSpan(TimeSpan.FromSeconds(10.0)) 
    | ActiveThing number -> Func(fun a b c -> Some(DateTime.Now)) 

何でも任意の引数をとり、Some 1を返すだけで、これをワイルドカードに置き換えることもできます。

let returnEitherFuncOrTimeSpan input = 
    match input with 
    | "should return TimeSpan" -> TimeSpan(TimeSpan.FromSeconds(10.0)) 
    | _ -> Func(fun a b c -> Some(DateTime.Now)) 

この関数は、最終的に戻って(引数またはタイプDateTime -> DateTime -> Option<DateTime> -> Option<DateTime>の2)カリー化関数として「のTimeSpanを返すべきである」あなたはそれを文字列を与えた場合、10秒の1)タイムスパンのいずれかを含む代数的データ型を返します。指定された引数についてはDateTime.Now)。

+0

ああ、私は混乱がどこから来たのか分かっています。本当に残念です。アクティブなパターンは実際に元のコードで行いました。簡略化のため単純化しましたが、回答に影響があった場合は残しておきたいと思います。 –

2

あなたがSystem.Func

let ReturnEitherFuncOrTimeSpan input = 
    match input with 
    | "should return TimeSpan" -> 
     let timespan = TimeSpan.FromSeconds(10.0) 
     FuncOrTimeSpan.TimeSpan(timespan) 
    | ActiveThing number -> 
      let curryResult = fun (a : DateTime) (b:DateTime) (c:DateTime option) -> Some(DateTime.Now) 
      let funcResult = System.Func<_,_,_,_>(curryResult) 
      FuncOrTimeSpan.Func(funcResult) 
+0

これで問題が解決したら、この質問を重複としてマークしてください。 –

+0

非常にクール、返信いただきありがとうございます。私は@ TheInnerLightの答えに印を付けることに決めました。あなたが気にしないことを願っています。私は質問していない私の質問のいくつかに答えた点を提供することが分かった。また、もし重複しているとすれば、重複したものとして印をつけてください。ドメイン知識の欠如が私に十分にグーグル・グーグルをしてくれるのを防ぐため、重複するものは見つかりませんでした。 :) –

+2

私はまったく気にしません。私たちはここに学びます。私はあなたがF#を楽しむために成長することを願っていますこれはF#に質問するのに最適な場所の一つです。あなたは[F#info tag](http://stackoverflow.com/tags/f%23/info)を見てください。私がこれを検索するために使用した主な用語は 'F#expected"でした。Func <"C#"あなたがそれを重複と見なすなら、あなた自身を重複としてマークすることができます。 –

関連する問題