加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

为Microsoft的Luis编写F#类型提供程序的好方法是什么?

发布时间:2020-12-14 05:45:15 所属栏目:Windows 来源:网络整理
导读:玩微软的Luis bot框架,我的“这将成为一个好的类型提供者”的感觉开始刺痛.不幸的是,类型提供者不能输出有区别的联盟.我希望做类似以下的事情,但这是不可能的: type Luis = LuisProvider@"LuisId",@"LuisPasskey"let IntentMatcher Intent = match intent w
玩微软的Luis bot框架,我的“这将成为一个好的类型提供者”的感觉开始刺痛.不幸的是,类型提供者不能输出有区别的联盟.我希望做类似以下的事情,但这是不可能的:

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

Luis意图及其参数都可通过Apis获得,使其成为typeProviderization的理想选择

这里参考的是一个C#bot示例的处理程序(我认为它可以更干净,在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);
}

无论如何,问题是:有没有更多建立类型提供者经验的人对我如何构建一个实际可行构建的可读dsl有任何好的想法吗?

解决方法

我对机器人框架并不是特别熟悉,但我可以对有区别的工会发表评论 – 我们在F#数据中遇到了类似的问题.

如果你有<一个名字=“字符串”/><两个id =“42”/>,那么提供有区别的联合的情况会很好,其中一个是字符串,另一个是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,startTime) -> 
     alarmHandler title startDate startTime)

现在我考虑一下,这可能会更好,但这取决于机器人框架的典型用途.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读