2016-03-25 26 views
1

Yaklaşık 2 saat F # için yeni oldum ve bir Func<DateTime, DateTime, Option<DateTime>, Option<DateTime>> veya TimeSpan olabilir ayrımcılıklı bir sendika türü bildirmek için bazı sorun yaşıyorum.Ayırtılı Func ve TimeSpan Birliği C#

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)) 

Ben bağırdı alıyorum: Bu fonksiyon çok fazla argüman alır veya işlev beklenmemektedir bir bağlamda kullanılır.

Lambdayı FuncOrTimeSpan.Func geçirebilmem için ne yapabilirim?

Ayrıca Func of DateTime -> DateTime -> Option<DateTime> -> Option<DateTime> gibi bir şeye yeniden yazmalı mıyım? Bunun ne anlama geldiğini bilmiyorum ve denediğimde yardımcı olmadı.

Muhtemelen C# 'dan bu işlevle arabirim oluşturmayı planladığımı not etmeliyim (ama belki de arayüzle etkileşime girmesi gereken C# kısmı da F #' ye yeniden yazılacak, böylece birlikte çalışmayı sonlandırmaya yönelik çözümler hala hoş geldiniz).

+0

ActiveThing ile ne yapmaya çalışıyorsunuz? –

+0

'ActiveThing 'tamam, bu sadece oyun cümlesi için aktif bir model, sorun yok. 'ActiveThing' dedim çünkü ismi hatırlayamadım ve bu konuda okuduğum sekmeyi bulamadım.Ayrıca yanlış yazdım, şimdi düzenleniyor. –

+0

@ TomášHübelbauer Orada bir problem var çünkü kısmi aktif modellerin sözdizimi doğru değil. Bkz. Https://msdn.microsoft.com/en-us/library/dd233248.aspx#Anchor_2 – TheInnerLight

cevap

3

Tam niyetinizi çözmeye çalışıyoruz sorunun nitel açıklamayla ne olduğunu bilmeden bu soruyu cevaplamak için oldukça zor üzere köri sonucu dönüştürmek gerekir olur net bir cevap vermekte yardımcı olun, ben de elimden gelenin en iyisini yapacağım.

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

Ben mevcut tip tanımı yanlış bir şey görmüyorum ama System.Func kullanarak F # fonksiyonlarını yazmak için çok sıradışı: Herşeyden

Öncelikle, tip tanımı aşağıdaki gibi görünmelidir. yerine curried argümanlardan tupled istedi Eğer

, bu gibi yazmak isterim: Eğer olsa öğreniyoruz iken

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

, sana farklılıkları anladım kadar ilk sopa tavsiye . Temel olarak, körelmiş argümanlar uygun kısmi uygulamayı mümkün kılarken, tupled argümanlar parametrelerin/geri dönüşlerin uygun şekilde gruplandırılmasını sağlar. F # 'da körlenmeyle ilgili daha fazla ayrıntı için bkz. https://fsharpforfunandprofit.com/posts/currying/.

Neyse, ilk tip tanımı ile Şu andan itibaren, işlevi daha sonra şu şekilde görünür: o yapmaz çünkü bu ActiveThing kısmi aktif desen kullanmayı tercih ediyorum neden bilmiyorum

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

şey. Sadece herhangi bir argümanı alır ve Some 1 döndürür, böylece bunu bir joker karakterle değiştirebilirsiniz.

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

Bu fonksiyon, o dize (bir bağımsız değişken olarak "TimeSpan dönmelidir" veya tip DateTime -> DateTime -> Option<DateTime> -> Option<DateTime> 2) curried fonksiyonu elde 10 saniye 1) bir zaman aralığı ya da ihtiva eden bir cebirsel veri türü döndürür sonunda döner Aksi halde, sağlanan tüm argümanlar için DateTime.Now.

+0

Oh, karışıklığın nereden geldiğini görüyorum, bunun için çok üzüldüm - aktif kalıp aslında orijinal kodumdaki şeyleri yaptım, sadece kısalık için basitleştirdim, ama cevabın üzerinde etkisi olması durumunda onu bırakmak istedim . –

2

Bir 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

Eğer bu sizin sorununuzu çözerse o zaman Bu soruyu bir kopya olarak işaretleyin. –

+0

Çok güzel, cevap için teşekkürler. @ TheInnerLight'ın cevabını işaretlemeye karar verdim, umarım sakıncası yoktur. Sormadığım bazı soruları yanıtlayan noktaları sağladım. Ayrıca, lütfen soruyu yinelenen olarak işaretleyin - eğer yinelenen bir tane bulamadım çünkü alan bilgisi eksikliğimi yeterince araştırmamı engelliyor, çünkü aranan terimlerin hiçbirini bilmiyorum. :) –

+2

Hiç umrumda değil. Öğrenmek için buradayız. Umarım F #'den hoşlanırsınız. Bu F # için soru sormak için en iyi yerlerden biridir. [F # info tag] 'a (http://stackoverflow.com/tags/f%23/info) göz atmalısınız. Googling için kullandığım anahtar terimler "F # beklenen" idi. Func <"C#' Eğer bir kopya olarak düşünürseniz, bunu kendiniz kopyalayabilirsiniz. –