Functional programming 组合两个匿名函数

Functional programming 组合两个匿名函数,functional-programming,sml,Functional Programming,Sml,我试图理解如何在SML中组合两个匿名函数 考虑: val x = fn 5 => 5 | 6 => 6; val y = fn 3 => 3 | 2 => 2; 我想通过组合x和y来创建函数z: 如何实现它?如果要定义一个函数,该函数将两个函数组合在一起,以便在第一个函数无法提供值时对第二个函数进行求值,则必须处理第一个函数失败时引发的匹配异常: val x = fn 5 => 5 | 6 => 6;

我试图理解如何在SML中组合两个匿名函数

考虑:

val x = fn 5 => 5
        |  6 => 6;

val y = fn 3 => 3
        |  2 => 2;
我想通过组合x和y来创建函数z:


如何实现它?

如果要定义一个函数,该函数将两个函数组合在一起,以便在第一个函数无法提供值时对第二个函数进行求值,则必须处理第一个函数失败时引发的匹配异常:

val x = fn 5 => 5
        |  6 => 6;

val y = fn 3 => 3
        |  2 => 2;

val z = fn i => x i
    handle Match => y i;
这有点难看,因为handle实际上并不符合函数式编程的精神,但它确实解决了问题。一个更简洁的解决方案是让z返回一个int选项,但这会改变函数的返回类型。结果可能是:

val x = fn 5 => SOME 5
        |  6 => SOME 6
        |  _ => NONE

val y = fn 3 => SOME 3
        |  2 => SOME 2
        |  _ => NONE

val z = fn i => case x i of
                  SOME j => SOME j
                | NONE => y i;

这一结果的优点是使所有编译器警告静音,但您需要像z在任何调用函数中那样使用模式匹配来解释输出。请注意,模式匹配能够提取值。在本例中,z只是转发了一些j,但如果需要,它可以直接使用整数值j。有关选项的更多信息,请参阅。

如果要定义一个函数,该函数将两个函数组合在一起,以便在第一个函数未能提供值时对第二个函数进行求值,则必须处理第一个函数失败时引发的匹配异常:

val x = fn 5 => 5
        |  6 => 6;

val y = fn 3 => 3
        |  2 => 2;

val z = fn i => x i
    handle Match => y i;
这有点难看,因为handle实际上并不符合函数式编程的精神,但它确实解决了问题。一个更简洁的解决方案是让z返回一个int选项,但这会改变函数的返回类型。结果可能是:

val x = fn 5 => SOME 5
        |  6 => SOME 6
        |  _ => NONE

val y = fn 3 => SOME 3
        |  2 => SOME 2
        |  _ => NONE

val z = fn i => case x i of
                  SOME j => SOME j
                | NONE => y i;

这一结果的优点是使所有编译器警告静音,但您需要像z在任何调用函数中那样使用模式匹配来解释输出。请注意,模式匹配能够提取值。在本例中,z只是转发了一些j,但如果需要,它可以直接使用整数值j。有关选项的更多信息,请参阅。

通常情况下,您不应该首先写入x和y中的不完整模式匹配。这将产生一个警告,你最好考虑一个错误。表示分部函数的推荐方法是返回一个选项。一旦你这样做了,你可以通过调用第一个,然后调用第二个,如果第一个没有返回,你就可以很容易地将它们组合起来。你通常不应该像在x和y中那样首先写不完整的模式匹配。这将产生一个警告,你最好考虑一个错误。表示分部函数的推荐方法是返回一个选项。一旦你这样做了,你就可以通过调用第一个,然后调用第二个,如果第一个没有返回的话。这就是我的想法。因此,SML不提供任何“干净”的解决方法,而不改变z的类型?@vesii改变z的类型,使其在没有错误捕获的情况下工作,还需要改变x和y的类型,以便它们也返回int选项。这是迄今为止最干净的解决方案。@vesii在答案中添加了一点内容,以显示基于选项的方法的外观。@vesii:无论哪种方式,您都必须提供某种结果,从第一个函数到合成运算符传递没有结果的信息。实现这一点的干净方法是通过一个错误感知的返回类型,例如“选项”,而不干净的解决方案是通过异常。这是表示null的两种方式。要组合查找,您还可以将查找表编码为值,例如通过基于查找的搜索树。这可能在运行时发生变化。SML并没有提供一个基于宏的解决方案,用于在编译时组合查找函数。这就是我的想法。因此,SML不提供任何“干净”的解决方法,而不改变z的类型?@vesii改变z的类型,使其在没有错误捕获的情况下工作,还需要改变x和y的类型,以便它们也返回int选项。这是迄今为止最干净的解决方案。@vesii在答案中添加了一点内容,以显示基于选项的方法的外观。@vesii:无论哪种方式,您都必须提供某种结果,从第一个函数到合成运算符传递没有结果的信息。实现这一点的干净方法是通过一个错误感知的返回类型,例如“选项”,而不干净的解决方案是通过异常。这是表示null的两种方式。要组合查找,您还可以将查找表编码为值,例如通过基于查找的搜索树。这可能在运行时发生变化。SML不提供用于在编译时组合查找函数的基于宏的解决方案。