字符串的想法是返回一个需要2个连续性的函数:一个用于字符串的末端,一个用于处理字符,以便我可以称其为:
fun collect stream =
let fun iter stream results =
stream (fn () => rev results)
(fn (index, char, stream) => iter stream (char::results))
in iter stream []
end
将所有字符都收集到列表中。 例如:呼叫
collect (stringChars "Hello")
将返回
[#"H", #"e", ...]
。 不幸的是,也没有打字:
collect
是我可以做这些键入的方法吗?
我尝试手动包括类型,但我最终遇到了一个循环问题(
Error: case object and rules do not agree [circularity]
rule domain: ((unit -> 'Z list) -> ('Y * 'Z * 'X -> 'W) -> 'V) * 'Z list
object: 'X * 'U
in expression:
(case (arg,arg)
of (stream,results) =>
(stream (fn () => rev results))
(fn (index,char,stream) => (iter stream) (char :: results)))
val it = () : unit
的类型需要
nextChar
的类型。
[编辑]:这是一个共同的LISP的一个示例:
kReadChar
我的问题是,可以进行此类检查吗?
首先,让您的第一个功能起作用:
nextChar
在调用它时,我无法更改格式化(主观),我会部分应用。现在的类型现在成功解决:
(defun string-chars (string)
(let ((length (length string)))
(labels ((next-char (index k-end-of-string k-read-char)
(if (= index length)
(funcall k-end-of-string)
(funcall k-read-char
index
(aref string index)
(lambda (k-end-of-string k-read-char)
(next-char (1+ index) k-end-of-string k-read-char))))))
(lambda (k-end-of-string k-read-char)
(next-char 0 k-end-of-string k-read-char)))))
(defun collect (stream)
(labels ((iter (stream result)
(funcall stream
(lambda () (reverse result))
(lambda (index char stream)
(declare (ignore index))
(iter stream (cons char result))))))
(iter stream '())))
(collect (string-chars "Hello"))
;; '(#\H #\e #\l #\l #\o)
您已经确定了第一步的类型的循环问题。 问题是一种类型不能包含自身。 例如,我们无法定义
fun stringChars string =
let
val len = size string
fun nextChar index kEndOfString kReadChar =
if len = index then
kEndOfString()
else
kReadChar(
index,
String.sub(string, index),
nextChar (index + 1) kEndOfString kReadChar
)
in
nextChar 0
end
nove,有一种有效实现这一目标的方法。
使用单个构造函数使用数据类型:
string -> (unit -> 'a) -> (int * char * 'a -> 'a) -> 'a