fold int选项功能

时间:2018-02-19 02:17:50

标签: polymorphism sml fold

我写了一个程序,它在列表中包含列表的整数并将它们加在一起。现在我想再次编写这个函数,但是使用int选项整数。

我从

改变了原来的功能
fun fold f base [] = base
  | fold f base (x::rest) = f x (fold f base rest);
fun add x y = x+y;
fun sumList L = fold add 0 L;

fun fold2 f base [] = SOME(base)
  | fold2 f base (x::rest) = f (SOME x) (fold2 f base rest);
fun add2 x y = SOME (x + y);
fun sumList2 L = fold2 add2 NONE L;

add和fold2函数都编译,但是当我尝试运行sumList2的变体时,我得到操作数并不同意错误。

1 个答案:

答案 0 :(得分:0)

有点不清楚选项的目的是什么;你想在 int选项列表中添加数字吗?例如。 [SOME 1, SOME 2, NONE, SOME 3]。甚至 int选项列表?例如。 [[SOME 1, NONE], [NONE, SOME 2, SOME 3], [], [NONE, NONE, NONE]]。或者您是否尝试在不包含可选值的列表上使用可选类型编写折叠?

你的问题在于f的论点类型。在fold2中,可以推断出类型为

'a option -> 'b option -> 'b option

因为第一个参数始终为(SOME x),其类型为'一个选项,第二个参数始终为(fold2 f base rest),其类型为'b选项< / em>因为fold2的基本情况,并且出于同样的原因返回'b选项。但是,add2的类型为

int -> int -> int option

您可以执行以下操作之一来解决此问题:

  • 您的add2假设其操作数是整数,而不是整数选项;即你正在写SOME (x + y),而你只能在数字时添加xy。根据您正在做的事情,add2可以将其操作数视为可选操作; e.g。

    fun add2 NONE b = b
      | add2 a NONE = a
      | add2 (SOME x) (SOME y) = SOME (x + y)
    

    会将NONE视为0。那就是这样。

    fun add2 a b = SOME (Option.getOpt (a, 0) + Option.getOpt (b, 0))
    

    但在add2 (NONE, NONE)NONESOME 0的情况下,它们会有所不同。

  • fold2SOME周围总是包围x的意义上是有点无意义的:如果总是,然后为什么要这样做?您可以fold2负责放弃NONE,例如

    fun fold2 f base [] = base
      | fold2 f base (NONE::rest) = fold2 f base rest
      | fold2 f base (SOME x::rest) = f x (fold2 f base rest)
    

    在这种情况下,其类型变为

    ('a -> 'b -> 'b) -> 'b -> 'a option list -> 'b
    

    并且您创建了一种特殊类型的折叠,同时丢弃NONE个。我可能更喜欢有一个单独的功能,并将其与常规折叠结合使用:

    fun fold f base [] = base
      | fold f base (x::rest) = f x (fold f base rest)
    
    fun somes [] = []
      | somes (NONE::xs) = somes xs
      | somes (SOME x::xs) = x::somes xs
    
    fun curry f x y = f (x, y)
    
    fun sumListOption xs = fold (curry op+) 0 (somes xs)
    

但是,这完全取决于你想要完成的事情。