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
很有用。