2016-08-19 6 views
3

MicrosoftのLuis + botフレームワークを利用しているので、私の「これは良いタイプのプロバイダになるだろう」という感覚が震え始めました。残念ながら、タイププロバイダは区別された共用体を出力できません。私は次のような何かを期待していたが、それは不可能です。MicrosoftのLuisのF#Type Providerを作成するにはどうすればよいですか?

type Luis = LuisProvider<@"LuisId",@"LuisPasskey"> 
let IntentMatcher Intent = 
    match intent with 
    | Luis.Intents.Greeting -> GreetingHandler() 
    | Luis.Intents.SetAlarm title startDate startTime -> AlarmHandler title startDate startTime 
    | _ -> CouldNotUnderstand() 

ルイス・インテントとそのパラメータは、すべての利用可能なAPIを経由してここに参考のためにtypeProviderization

のための有力な候補作っていますたとえば、C#のボットからのハンドラ(と思うきれいかもしれない、とF#で安全な、よりタイプ):

public const string Entity_Alarm_Title = "builtin.alarm.title"; 
public const string Entity_Alarm_Start_Time = "builtin.alarm.start_time"; 
public const string Entity_Alarm_Start_Date = "builtin.alarm.start_date"; 
public const string DefaultAlarmWhat = "default"; 

[LuisIntent("builtin.intent.alarm.set_alarm")] 
public async Task SetAlarm(IDialogContext context, LuisResult result) 
{ 
     EntityRecommendation title; 
     if (!result.TryFindEntity(Entity_Alarm_Title, out title)) 
     { 
      title = new EntityRecommendation(type: Entity_Alarm_Title) { Entity = DefaultAlarmWhat }; 
     } 
     EntityRecommendation date; 
     if (!result.TryFindEntity(Entity_Alarm_Start_Date, out date)) 
     { 
      date = new EntityRecommendation(type: Entity_Alarm_Start_Date) { Entity = string.Empty }; 
     } 
     EntityRecommendation time; 
     if (!result.TryFindEntity(Entity_Alarm_Start_Time, out time)) 
     { 
      time = new EntityRecommendation(type: Entity_Alarm_Start_Time) { Entity = string.Empty }; 
     } 
     var parser = new Chronic.Parser(); 
     var span = parser.Parse(date.Entity + " " + time.Entity); 
     if (span != null) 
     { 
      var when = span.Start ?? span.End; 
      var alarm = new Alarm() { What = title.Entity, When = when.Value }; 
      this.alarmByWhat[alarm.What] = alarm; 
      string reply = $"alarm {alarm} created"; 
      await context.PostAsync(reply); 
     } 
     else 
     { 
      await context.PostAsync("could not find time for alarm"); 
     } 
     context.Wait(MessageReceived); 
} 

はとにかく質問です:より多くの経験の建物のタイププロバイダと誰もがどのように私ができる上の任意の良いアイデアを持っていますacである読み取り可能なdslを構造化するビルドすることは可能ですか?

答えて

7

私は特にボットのフレームワークに精通していませんが、私は差別化されたユニオンにコメントすることができます - 私たちはF#データの同様の問題に直面しています。

<One name="string" /><Two id="42" />をお持ちの場合は、ケースOne of stringTwo of intで区別されたユニオンを提供すると良いでしょう。私たちが代わりにやっていることは、我々は種類を提供していることである:

type OneOrTwo = 
    member One : option<string> 
    member Two : option<int> 

あなたは同じパターンに従うと、このようになりますAPIを公開することができます:

type Luis = LuisProvider<"LuisId", "LuisPasskey"> 

let intentMatcher (intent:Luis.Intents) = 
    match intent.Greetings, intent.SetAlarm with 
    | Some(), _ -> greetingHandler() 
    | _, Some(title, startDate, startTime) -> alarmHandler title startDate startTime 
    | _ -> couldNotUnderstand() 

Luis.Connect().OnIntent 
|> Observable.subscribe intentMatcher 

それは、差別組合ほどエレガントではありませんそれは技術的に実行可能でなければなりません。今、私はそれについて考える、これはおそらくよりよいだろう

type Luis = LuisProvider<"LuisId", "LuisPasskey"> 

let luis = Luis.Connect() 

luis.BuiltIn.Greetings 
|> Observable.add greetingHandler 

luis.BuiltIn.SetAlarm 
|> Observable.add (fun (title, startDate, startTime) -> 
    alarmHandler title startDate startTime) 

を:

は、私は別の代替は、別々の事象として、個々のアクションのためのハンドラを公開することであろうと、あなたはこのような何かを書くことができたとしボットフレームワークの典型的な用途に依存します。

+0

あなたは星です! 2人の後者は完璧に見える:) –

関連する問題