在SML出现问题时展平数据类型列表

问题描述

我对作业有疑问,问题是

有使用的数据类型:

datatype 'a llist = LList of 'a llist list| Elem of 'a;

嵌套列表由多态类型的元素或嵌套列表的列表组成。的 以下是一些示例:

Elem(1);
LList [];
LList([Elem(1),LList([Elem(2),LList([Elem 1,Elem(3)]),Elem(4)])]);

编写一个函数拼合,将嵌套列表作为输入并返回 所有的平面清单 嵌套列表中的元素。请注意,结果列表中的元素顺序相同 就像在嵌套列表中一样。

- flatten;
val flatten = fn : 'a llist -> 'a list

Examples:

- flatten(Elem(3));
val it = [3] : int list
- flatten(LList([]));
val it = [] : ?.X1 list
- flatten(LList([Elem(1),LList([]),Elem(4)]
));
val it = [1,2,3,4] : int list

但是我的代码是

fun flatten Elem x = [x] | LList x = (List.concat (map (fn a => flatten(a)) x));

有问题

- fun flatten Elem x = [x] | LList x = (List.concat (map (fn a => flatten(a)) x));
stdIn:13.1-17.71 Error: clauses do not all have same function name

stdIn:13.1-17.71 Error: clauses do not all have same number of patterns

stdIn:17.4-17.8 Error: data constructor Elem used without argument in pattern

stdIn:13.1-17.71 Error: types of rules do not agree [tycon mismatch]
  earlier rule(s): 'Z * 'Y -> 'Y list
  this rule: 'X list -> 'W list
  in rule:
    x => List.concat ((map (fn a => flatten a)) x)

stdIn:13.1-17.71 Error: right-hand-side of clause does not agree with function result type [tycon mismatch]
  expression:  'Z -> 'Z list
  result type:  'Y list
  in declaration:
    flatten =
      (fn arg =>
            (fn arg =>
                  (case (arg,arg)
                  of (_,x) => x :: nil
                   | x => List.concat ((map <exp>) x))))

我不知道我的代码出了什么问题。

解决方法

您的代码中存在一些语法问题。

否则逻辑就可以了。

这是更正的版本:

fun flatten (Elem x) = [x]
  | flatten (LList x) = (List.concat (map (fn a => flatten(a)) x));
,

由于quoify提供了完整的解决方案,因此以下是使用显式递归而不是库函数的解决方案,以及quoify的concat-map解决方案的整理版本:

fun flatten (Elem x) = [x]
  | flatten (LList []) = []
  | flatten (LList (LL::LLs)) = flatten LL @ flatten (LList LLs)

这里LL'alist 是第一个子分支,而LLs'alist列表是其余子支行。类型名称​​'a llist 可能会造成一些混淆,因为它是树时类似于列表。因此,您可以将LL视为树,并将LLs视为树列表。

基本方法是在具有一个元素的树,具有零个子分支的树以及具有一个或多个子分支的树上进行模式匹配。然后将其转变为使用列表组合器(例如mapconcat)的解决方案,您可以确定递归方案:不必将递归分为“空” /“非空”模式,而是要完成整个任务递归到map

(* BROKEN *)
fun flatten (Elem x) = [x]
  | flatten (LList ts) = map flatten ts

编译器给我们的问题是:

! Toplevel input:
!   | flatten (LList ts) = map flatten ts;
!                          ^^^^^^^^^^^^^^
! Type clash: expression of type
!   'a list list
! cannot have type
!   'a list
! because of circularity

因此,由于flatten返回一个'列表,因此map flatten必须返回一个'一个列表列表,因为它需要多个树并为每个列表生成一个扁平化列表。但是,'列表列表'a列表足够接近,我们可以使用{{ 1}}:

List.concat

您还可以为此特定组合创建一个辅助函数:

fun flatten (Elem x) = [x]
  | flatten (LList ts) = List.concat (List.map flatten ts)

相关问答

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