Functional programming 如何在SML中打印if语句
这是我试过的代码Functional programming 如何在SML中打印if语句,functional-programming,sml,ml,Functional Programming,Sml,Ml,这是我试过的代码 fun printsl([], k) = true | printsl(h::t) = if k > h then print(h) andalso printsl(t); 但是当我运行代码时,我得到以下错误 = stdIn:4.68-7.8 Error: syntax error: deleting SEMICOLON ID stdIn:8.1 Error: syntax error found at EOF 该函数的目标是打印列表中小于值k的任何
fun printsl([], k) = true
| printsl(h::t) = if k > h then print(h) andalso printsl(t);
但是当我运行代码时,我得到以下错误
= stdIn:4.68-7.8 Error: syntax error: deleting SEMICOLON ID
stdIn:8.1 Error: syntax error found at EOF
该函数的目标是打印列表中小于值k的任何数字,这里有一些错误。让我们从函数签名开始 在第一行,您的函数接受两个参数,一个空列表和
k
的任何类型(这还不重要)。然后在第二行,函数只接受一个参数,一个非空列表
这两行应该匹配,看起来像:
funprintsl([],k)=。。。
|printsl(h::t,k)=。。。
现在让我们考虑一下和的用法andalso
是一个运算符,它接受两个布尔值并返回一个布尔值。可以认为它具有签名bool*bool->bool
您的使用print(h)和also printsl(t)
与此签名不匹配
print
的类型是string->unit
,因此print(h)
的类型是unit
(假设h
是字符串)。因此,和
的用法是不正确的,因为每侧的类型都不是布尔
我们不需要使用和,只需执行这两条语句(print(h);printsl(t,k))
。像这样的序列是返回最后一个值的表达式。也就是说(x;y;z)
返回z
fun printsl([],k)=真
|printsl(h::t,k)=如果h
但是,由于SML中的if-else构造是一个表达式,必须具有匹配的else,因此这仍然是错误的,因此您可以使用以下任意一种:
fun printsl([],k)=真
|printsl(h::t,k)=
如果h
fun printsl([],k)=真
|printsl(h::t,k)=(
如果h
我个人更喜欢后者,因为它可以防止重复printsl
此代码将编译,但签名错误。当我们直接使用h
作为print
的参数时,其类型被推断为字符串
。这意味着编译器确定printsl
具有类型string list*string->bool
,而我们的目标是int list*int->bool
可以通过将调用print(h)
更改为print(Int.toString h)
来纠正此问题,为我们提供:
fun printsl([],k)=真
|printsl(h::t,k)=(
如果h
现在,这是一个函数,它将打印给定列表中小于k
的所有值,但它始终返回true。这没有提供额外的信息,因此我倾向于将签名更改为int list*int->unit
,最后给出:
funprintsl([],k)=()
|printsl(h::t,k)=(
如果h
整个程序也可以使用List.app
和List.filter
以更实用的方式编写
funprintsl(xs,k)=
List.app
(fn y=>打印(Int.toString y))
(List.filter)
(fn x=>x
必须有一个else
分支-条件是一个表达式,而不是一个语句,因此在所有情况下都必须产生一个值。此外,所有定义子句必须采用相同数量和类型的参数-您有一个采用('a list*'b)
,另一个采用int list
(并且k
不受该子句的约束)。也许你应该看一下SML的简介?另外,print
的类型是string->unit
。它不能打印整数,结果也不能是和
的操作数。另一方面,如果这是SML简介中的一个练习,它说的是“输出”,那可能是在返回值的意义上,不需要打印任何内容。如果确实需要打印,您可能会发现函数Int.toString:Int->string
很有用。