1

那里有用于 SML 的“不错”的日志记录/调试库吗?我正在调试一些旨在镜像一些 Java 代码的 SML 代码。我有兴趣让两个程序在计算过程中打印出中间值。我发现这个库可以获得类似于 C/Java 的东西printf(),这是一个很大的帮助。有很多优秀的 Java 日志库,所以那里不应该有任何问题。

然而,将打印语句添加到 SML 会增加大量的代码行,并且通常看起来丑陋和糟糕。有没有很好的方法来做到这一点?甚至可能是 Python 的装饰器之类的东西?

这是我所指的一个例子。使用日志记录:

fun execute (points : Point.t list,
             nClusters : int,
             threshold : real,
             randomPtr : Random.rand,
             debug : bool) =
    let
        (* helper function for debugging *)
        fun printIterationInfo (index, points) =
            print(genericDebugFmt "\nLoop iteration index: " 
                                  index 
                                  "\npoints: " 
                                  (map Point.featuresRepr points))                  
        val initialClusters = initializeClusters(points, nClusters, randomPtr, debug)
        val _ = if debug then
                    printIterationInfo (~1, initialClusters)
                else ()
        fun loop (10, clusterCenters) = 
            if debug then
                (printIterationInfo (10, clusterCenters);
                clusterCenters)
            else
                clusterCenters
          | loop (index, clusterCenters) = 
            (* wow, adding logging is cumbersome... *)
            let
                val ans = work(points, clusterCenters, debug)
            in
                if debug then
                    (printIterationInfo (index, ans);
                     loop (index + 1, ans))
                else 
                    loop(index + 1, ans)        
            end
    in
        loop (0, initialClusters)
    end
end 

不记录:

fun execute (points : Point.t list,
             nClusters : int,
             threshold : real,
             randomPtr : Random.rand,
             debug : bool) =
    let
        val initialClusters = initializeClusters(points, nClusters, randomPtr, debug)

        fun loop (10, clusterCenters) = clusterCenters
          | loop (index, clusterCenters) = 
            loop(index + 1, ans)        
    in
        loop (0, initialClusters)
    end
end 
4

1 回答 1

1

SML有printf: http: //mlton.org/Printf

它可能会使一些打印语句看起来更好看,但它并不能解决在程序中到处添加打印调试的冗长问题。

如果您想要侵入性较小的调试功能,请尝试执行 Haskell 的跟踪之类的操作:

fun trace msg f = (print msg; f ())

而不是

fun foo x = 2 + x

你做

fun foo x = trace "Hmm" (fn _ => 2 + x)

诚然,额外的匿名函数不是很好,但如果我们希望在表达式可能崩溃print "Hmm"之前发生效果,则它是必要的。2 + x

现在,如果你想要你的调试标志,你可以把这个检查嵌入到跟踪函数中:

fun trace msg thunk = (if debug then print msg else (); thunk ())

... wheredebug是先前定义的。

于 2013-11-12T08:17:01.240 回答