【问题标题】:Is there a way to get a Curried form of the binary operators in SML/NJ?有没有办法在 SML/NJ 中获得二元运算符的 Curried 形式?
【发布时间】:2010-11-26 02:25:02
【问题描述】:

例如,而不是

- op =;
val it = fn : ''a * ''a -> bool

我宁愿有

- op =;
val it = fn : ''a -> ''a -> bool

用于

val x = getX()
val l = getList()
val l' = if List.exists ((op =) x) l then l else x::l

例如,显然我可以自己做到这一点,

val l' = if List.exists (fn y => x = y) l then l else x::l

但我想确保我不会错过更优雅的方式。

【问题讨论】:

    标签: operators sml currying smlnj


    【解决方案1】:

    你可以编写一个辅助函数来对函数进行curry:

    fun curry f x y = f (x, y)
    

    然后你可以做类似的事情

    val curried_equals = curry (op =)
    val l' = if List.exists (curried_equals x) l then l else x::l
    

    【讨论】:

    • +1。而反过来,你可以写fun decurry f (x, y) = f x y。 (这对于调用像 foldl 这样需要二进制函数的函数很有用。)
    【解决方案2】:

    我对 SML 的了解很少,但我翻阅了 Ullman 的书,找不到将接受元组的函数转换为柯里化函数的简单方法。它们有两个不同的签名,并且彼此不直接兼容。

    我认为您将不得不自己动手。

    或者切换到 Haskell。

    编辑:我已经考虑过了,现在知道为什么一个与另一个不一样了。在 SML 中,几乎所有您习惯使用的函数实际上只接受一个参数。碰巧的是,大多数时候你实际上是在传递一个包含多个元素的元组。尽管如此,元组是一个单一的值,并被函数视为这样。您不能将此类函数传递给部分元组。要么是整个元组,要么什么都没有。

    根据定义,任何接受多个参数的函数都是柯里化的。当您定义一个接受多个参数的函数(而不是具有多个元素的单个元组)时,您可以部分应用它并将其返回值用作另一个函数的参数。

    【讨论】:

    • 您声明“根据定义,任何接受多个参数的函数都是柯里化的”。好吧,我认为 ('a -> 'b -> 'c) 类型的函数也只接受一个参数 ('a),它恰好返回另一个类型为 ('b -> 'c) 的函数)。这是因为“->”运算符是右结合的:('a -> 'b -> 'c) = ('a -> ('b -> 'c))。部分应用只是由此产生的结果。函数应用是左关联的,因此 (myFun arg1 arg2 arg3) = (((myFun arg1) arg2) arg3)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-23
    • 2022-10-15
    • 1970-01-01
    • 2010-11-21
    • 2014-09-30
    • 1970-01-01
    • 2021-06-25
    相关资源
    最近更新 更多