如何返回一些列表而不是普通列表?

问题描述

我正在尝试实现一个程序,该程序需要一个字符串和一个列表,如果找不到任何匹配项,则返回NONE,如果找到则不包含该元素的列表。

fun all_except_option ("string",["he","she","string"]) = SOME["he","she"]

我设法使其正常运行,但是没有选项类型,也不知道如何使其返回SOME list而不是普通列表。

fun all_except_option(str,lst)=
    case lst of
         [] => []
      | x::lst' => if same_string(x,str) = false
                   then let fun append (word,list) = word::list
                        in append(x,[]) :: all_except_option(str,lst')
                        end
                   else all_except_option(str,lst')

解决方法

谢谢。我设法使其正常工作,但我仍然不了解“其他情况”以及程序如何处理它。这是工作代码。如果您能向我解释“的其他情况下all_except_option(str,list')”,我将非常高兴。

fun all_except_option(str,list)=
    case list of
    [] => NONE
      | x::list' => if same_string(x,str)  then
            
              SOME( list')
                                  
            else case  all_except_option(str,list') of
                 NONE=>NONE
               | SOME list'=>SOME(x::list')
,

实现一个程序,该程序需要一个字符串和一个列表,如果找不到任何匹配项,则返回NONE;如果找到,则返回不包含元素的列表。

all_except_option ("string",["he","she","string"]) = SOME ["he","she"]

SOME []NONE有何不同?就像在其中,如果此函数仅返回一个列表,则可以说删除"string"的出现不会导致其他字符串:该列表已经为空,或者仅包含"string"的出现。我不确定为什么NONE vs. SOME []在一种情况下胜过另一种情况。

因此,更好的功能是仅返回简单列表的功能:

fun except (x,ys) = List.filter (fn y => x <> y)

何时返回'一个选项有用吗?

例如,当返回类型尚无法表示没有结果时:

fun lookup k1 [] = NONE
  | lookup k1 ((k2,v)::pairs) =
      if k1 = k2
      then SOME v
      else lookup k1 pairs

此函数返回0或1的东西。但这也是一个简单的函数,因为它永远不会在递归过程中聚合结果。当递归函数需要解压缩递归结果时,它们返回诸如'a option 之类的复合数据类型时,递归函数变得复杂。

一个很好的例子是eval函数有时会失败:

datatype expr
  = Add of expr * expr
  | Sub of expr * expr
  | Mul of expr * expr
  | Div of expr * expr
  | Int of int

fun eval (Int n) = SOME n
  | eval (Add (e1,e2)) = evalHelper ( op+ ) (e1,e2)
  | eval (Sub (e1,e2)) = evalHelper ( op- ) (e1,e2)
  | eval (Mul (e1,e2)) = evalHelper ( op* ) (e1,e2)
  | eval (Div (e1,e2)) =
      case eval e1 of
           NONE => NONE
         | SOME x => case eval e2 of
                          NONE => NONE
                        | SOME 0 => NONE
                        | SOME y => SOME (x div y)

and evalHelper binop (e1,e2) =
      case eval e1 of
           NONE => NONE
         | SOME x => case eval e2 of
                          NONE => NONE
                        | SOME y => SOME (binop (x,y))

此处返回类型为 int选项,这意味着您最常返回 int ,但是如果除以零,则结果为“无值” ,因此我们不会引发异常,而是返回NONE,这使得我们必须在有结果的情况下返回SOME n,以便在两种情况下都适合该类型。

快速演示:

- eval (Div (Int 5,Int 2));
> val it = SOME 2 : int option
- eval (Div (Int 5,Int 0));
> val it = NONE : int option
- eval (Div (Int 2,Sub (Int 3,Int 3)));
> val it = NONE : int option
- eval (Div (Int 0,Int 1));
> val it = SOME 0 : int option

这里SOME 0的实际含义是“结果为0”,这与“不能除以零”不同。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...