展平SML上的数据类型列表获取问题
我有一个关于家庭作业的问题,问题是 使用的数据类型如下:展平SML上的数据类型列表获取问题,sml,flatten,Sml,Flatten,我有一个关于家庭作业的问题,问题是 使用的数据类型如下: 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)])]); 编写一个函数flant,该函数接受嵌套列表作为输入并返回 一份简单的清单 嵌套
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)])]);
编写一个函数flant,该函数接受嵌套列表作为输入并返回
一份简单的清单
嵌套列表中的元素。请注意,结果列表中的元素顺序相同
如嵌套列表中所示
但我的密码是
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]| LList x=(List.concat(map(fn a=>flatten(a))x));
stdIn:13.1-17.71错误:子句不都具有相同的函数名
stdIn:13.1-17.71错误:子句的模式数不尽相同
stdIn:17.4-17.8错误:在模式中使用的数据构造函数元素没有参数
stdIn:13.1-17.71错误:规则类型不一致[tycon不匹配]
早期规则:“Z*”Y->“Y列表
此规则:“X列表->”W列表
按照规则:
x=>List.concat((映射(fn a=>flatte a))x)
stdIn:13.1-17.71错误:条款右侧与功能结果类型不一致[tycon不匹配]
表达式:“Z->”Z列表
结果类型:“Y列表”
在声明中:
压扁=
(fn arg=>
(fn arg=>
(案例(arg,arg)
of(ux)=>x::nil
|x=>List.concat((map)x)))
我不知道我的代码有什么问题。您的代码中有一些语法问题 否则,逻辑是正确的 以下是更正的版本:
fun flatten(元素x)=[x]
|展平(LList x)=(List.concat(map(fn a=>展平(a))x));
由于quoify提供了一个完整的解决方案,下面是一个使用显式递归而非库函数的解决方案,以及quoify的concat map解决方案的精简版本:
fun flatten (Elem x) = [x]
| flatten (LList []) = []
| flatten (LList (LL::LLs)) = flatten LL @ flatten (LList LLs)
这里,LL
是作为第一个子分支的“ALLIST”,而LLs
是作为剩余子分支的“ALLIST”列表。llist的类型名可能会有点混淆,因为当它是一个树时,它类似于一个列表。因此,您可以将LL
视为一棵树,将LLs
视为一列树
基本方法是对具有一个元素的树、具有零分支的树以及具有一个或多个分支的树进行模式匹配。将此转换为使用列表组合符(如map
和concat
)的解决方案,您可以确定递归方案:与其将递归拆分为“空”/“非空”模式,不如将整个递归任务交给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
因此,既然flatte
返回一个“a列表”,那么map flatte
就必须返回一个“a列表”,因为它需要多个树并为每个树生成一个展平列表。但是“a列表”与“a列表”非常接近,我们可以使用list.concat将内部列表合并成一个大列表:
fun flatten (Elem x) = [x]
| flatten (LList ts) = List.concat (List.map flatten ts)
您还可以为此特定组合创建帮助器函数:
fun concatMap f = List.concat o List.map f
fun flatten (Elem x) = [x]
| flatten (LList ts) = concatMap flatten ts
fun concatMap f = List.concat o List.map f
fun flatten (Elem x) = [x]
| flatten (LList ts) = concatMap flatten ts