问题描述 投票:0回答:1

字符串的想法是返回一个需要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,有一种有效实现这一目标的方法。

使用单个构造函数使用数据类型:

types functional-programming sml circular-reference continuation-passing
1个回答
1
投票

我建议您在查看下面的解决方案之前最多可以使用它长达一个小时。

string -> (unit -> 'a) -> (int * char * 'a -> 'a) -> 'a

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.