如何从标准输入读取?
How to read from stdin?
如何在 Clean 中执行此操作?
伪代码:
loop:
input = read_stdin
if input == "q":
break loop
else:
print "you input: ", input
其实我也看过一些pdf。但是我有一个想象,很难处理stdin和stdout。我可以有一个使用 stdio 的代码示例吗?
按照基兰的指示,我完成了我的小程序。
module std_in_out_loop
import StdEnv
loop :: *File -> *File
loop io
# io = fwrites "input your name: " io
# ( name, io ) = freadline io
# name = name % ( 0, size name - 2 )
| name == "q"
# io = fwrites "Bye!\n" io
= io
| name == ""
# io = fwrites "What's your name?\n" io
= loop io
| otherwise
# io = fwrites ( "hello " +++ name +++ "\n" ) io
= loop io
Start:: *World -> *World
Start world
# ( io, world ) = stdio world
# io = loop io
# ( ok, world ) = fclose io world
| not ok = abort "Cannot close io.\n"
| otherwise = world
来自 Clean 2.2 manual,第 9 章:
Although Clean is purely functional, operations with side-effects (I/O operations, for instance) are permitted. To achieve
this without violating the semantics, the classical types are supplied with so called uniqueness attributes. If an argument
of a function is indicated as unique, it is guaranteed that at run-time the corresponding actual object is local, i.e. there are
no other references to it. Clearly, a destructive update of such a “unique object” can be performed safely.
具体来说,您可以将 Start
设为一个从 *World
到 *World
的函数,它通常的元数为 0(不接受任何参数)。这个想法是我们现在有一个改变世界的功能,这意味着副作用是允许的(它们不再是真正的副作用,而是对世界的操作)。
*
表示World
类型的唯一性。这意味着您永远不能拥有两个 world 参数实例。例如,以下将给出编译时唯一性错误:
Start :: *World -> *(*World, *World)
Start w = (w, w)
要使用标准 IO,您将需要 StdEnv
中 StdFile
模块的函数。您需要的功能是:
stdio :: !*World -> *(!*File, !*World)
fclose :: !*File !*World -> !(!Bool, !*World)
我稍微简化了类型,实际上它们来自 class FileSystem
。 stdio
从一个世界打开一个 独特的 File
以及 returns 修改后的新世界。 fclose
关闭世界中的文件,returns 成功标志和修改后的世界。
然后,要从该 stdio 文件读取和写入,您可以使用:
freadline :: !*File -> *(!*String, !*File)
fwrites :: !String !*File -> !*File
freadline
将一行读入字符串,包括换行符。 fwrites
将字符串写入文件,通常您希望在写入 stdio 时包含换行符。
放在一起:
Start :: *World -> *World
Start w
# (io,w) = stdio w // open stdio
# io = fwrites "What is your name?\n" io // ask for name
# (name,io) = freadline io // read in name
# name = name % (0, size name - 2) // remove \n from name
# io = fwrites ("Hello, " +++ name +++ "!\n") io // greet user
# (ok,w) = fclose io w // close stdio
| not ok = abort "Couldn't close stdio" // abort in case of failure
= w // return world from Start
#
语法对您来说可能是新的。它是一种 let
允许你对文件(或其他东西)使用相同的名称,这比使用更方便,例如:
Start w = w3
where
(io, w1) = stdio w
io1 = fwrites "What is your name?\n" io
(name, io2) = freadline io1
//...
(ok, w3) = fclose io10 w2
现在您应该能够使用辅助函数 loop :: *File -> *File
在伪代码中执行您想要的操作,该辅助函数递归调用自身直到输入 q
。
函数比 freadline
和 fwrites
多,请参阅 StdFile.dcl
以获取想法。
如何在 Clean 中执行此操作?
伪代码:
loop:
input = read_stdin
if input == "q":
break loop
else:
print "you input: ", input
其实我也看过一些pdf。但是我有一个想象,很难处理stdin和stdout。我可以有一个使用 stdio 的代码示例吗?
按照基兰的指示,我完成了我的小程序。
module std_in_out_loop
import StdEnv
loop :: *File -> *File
loop io
# io = fwrites "input your name: " io
# ( name, io ) = freadline io
# name = name % ( 0, size name - 2 )
| name == "q"
# io = fwrites "Bye!\n" io
= io
| name == ""
# io = fwrites "What's your name?\n" io
= loop io
| otherwise
# io = fwrites ( "hello " +++ name +++ "\n" ) io
= loop io
Start:: *World -> *World
Start world
# ( io, world ) = stdio world
# io = loop io
# ( ok, world ) = fclose io world
| not ok = abort "Cannot close io.\n"
| otherwise = world
来自 Clean 2.2 manual,第 9 章:
Although Clean is purely functional, operations with side-effects (I/O operations, for instance) are permitted. To achieve this without violating the semantics, the classical types are supplied with so called uniqueness attributes. If an argument of a function is indicated as unique, it is guaranteed that at run-time the corresponding actual object is local, i.e. there are no other references to it. Clearly, a destructive update of such a “unique object” can be performed safely.
具体来说,您可以将 Start
设为一个从 *World
到 *World
的函数,它通常的元数为 0(不接受任何参数)。这个想法是我们现在有一个改变世界的功能,这意味着副作用是允许的(它们不再是真正的副作用,而是对世界的操作)。
*
表示World
类型的唯一性。这意味着您永远不能拥有两个 world 参数实例。例如,以下将给出编译时唯一性错误:
Start :: *World -> *(*World, *World)
Start w = (w, w)
要使用标准 IO,您将需要 StdEnv
中 StdFile
模块的函数。您需要的功能是:
stdio :: !*World -> *(!*File, !*World)
fclose :: !*File !*World -> !(!Bool, !*World)
我稍微简化了类型,实际上它们来自 class FileSystem
。 stdio
从一个世界打开一个 独特的 File
以及 returns 修改后的新世界。 fclose
关闭世界中的文件,returns 成功标志和修改后的世界。
然后,要从该 stdio 文件读取和写入,您可以使用:
freadline :: !*File -> *(!*String, !*File)
fwrites :: !String !*File -> !*File
freadline
将一行读入字符串,包括换行符。 fwrites
将字符串写入文件,通常您希望在写入 stdio 时包含换行符。
放在一起:
Start :: *World -> *World
Start w
# (io,w) = stdio w // open stdio
# io = fwrites "What is your name?\n" io // ask for name
# (name,io) = freadline io // read in name
# name = name % (0, size name - 2) // remove \n from name
# io = fwrites ("Hello, " +++ name +++ "!\n") io // greet user
# (ok,w) = fclose io w // close stdio
| not ok = abort "Couldn't close stdio" // abort in case of failure
= w // return world from Start
#
语法对您来说可能是新的。它是一种 let
允许你对文件(或其他东西)使用相同的名称,这比使用更方便,例如:
Start w = w3
where
(io, w1) = stdio w
io1 = fwrites "What is your name?\n" io
(name, io2) = freadline io1
//...
(ok, w3) = fclose io10 w2
现在您应该能够使用辅助函数 loop :: *File -> *File
在伪代码中执行您想要的操作,该辅助函数递归调用自身直到输入 q
。
函数比 freadline
和 fwrites
多,请参阅 StdFile.dcl
以获取想法。