我尝试了以下方法:
fun consAll (nil, n) = [n] | consAll ((x::xs), n) = [[n::x], [consAll(xs, n)]];
但它返回此错误:
“错误:运算符和操作数不同意[循环]运算符域:'Z列表列表*'Z列表列表操作数:'Z列表列表*'表达式中的Z列表:((n :: x):: nil):( consAll(,):: nil):: nil“
请告诉我哪里出错了,我是SML的初学者 .
SML列表构造语法并不完全简单 . 由于我们使用 [...] 来构造文字列表,因此我们很有可能认为我们也可以使用该符号来将列表和cons元素解构到列表的头部(例如,我们可以在Prolog中) . 但是cons运算符 :: 只是一个中缀值构造函数,它接受 'a 类型的项目和 'a list 类型的列表,并返回一个新的列表,其中项目consed到列表的头部 . 如果然后将结构的评估结果放在方括号中,那么现在已将结果列表包装在另一个列表中:
[...]
::
'a
'a list
- val xs = [2,3,4]; val xs = [2,3,4] : int list - [1::xs]; val it = [[1,2,3,4]] : int list list
您的定义中还有两个错误:
首先,当你想要在第二个保护函数定义的主体中列出一个列表的尾部时,你正在创建一个两项列表 .
其次,你的基础不正确:
fun consAll (nil, n) = [n]
这表示,如果列表列表为空,则返回包含要在每个列表上进行的项目的单例列表 . 但是你要定义一个函数,它应该将 n 放在每个列表的头部,这是第一个参数中列表的成员 . 当你在第一个参数中用完列表时,你应该只返回一个空列表,因为没有更多的列表要被强制转换 . 合理?
n
以下是编写所描述函数的两种方法 . 一个使用简单的递归,另一个使用高阶函数 List.map :
List.map
fun consAll ([], _) = [] | consAll ((x::xs), n) = (n::x) :: consAll(xs, n) fun mapCons x lists = List.map (fn ls => x :: ls) lists
[[n::x], [consAll(xs, n)]] 创建一个双元素列表,但您希望前置到列表中 . 请改用 (n :: x) :: consAll(xs, n) .
[[n::x], [consAll(xs, n)]]
(n :: x) :: consAll(xs, n)
2 回答
SML列表构造语法并不完全简单 . 由于我们使用
[...]
来构造文字列表,因此我们很有可能认为我们也可以使用该符号来将列表和cons元素解构到列表的头部(例如,我们可以在Prolog中) . 但是cons运算符::
只是一个中缀值构造函数,它接受'a
类型的项目和'a list
类型的列表,并返回一个新的列表,其中项目consed到列表的头部 . 如果然后将结构的评估结果放在方括号中,那么现在已将结果列表包装在另一个列表中:您的定义中还有两个错误:
首先,当你想要在第二个保护函数定义的主体中列出一个列表的尾部时,你正在创建一个两项列表 .
其次,你的基础不正确:
这表示,如果列表列表为空,则返回包含要在每个列表上进行的项目的单例列表 . 但是你要定义一个函数,它应该将
n
放在每个列表的头部,这是第一个参数中列表的成员 . 当你在第一个参数中用完列表时,你应该只返回一个空列表,因为没有更多的列表要被强制转换 . 合理?以下是编写所描述函数的两种方法 . 一个使用简单的递归,另一个使用高阶函数
List.map
:[[n::x], [consAll(xs, n)]]
创建一个双元素列表,但您希望前置到列表中 . 请改用(n :: x) :: consAll(xs, n)
.