Search code examples
algorithmoptimizationsmlsmlnj

SML : Replacing a concat by printing the string directly


I've got a function which is correctly working for now... But which is unfortunately constructing a very big string before displaying it.

I would like to display every string directly instead of concatening them but I don't know how to do it...

Here is the function:

fun getBlocked w =
    case BlockingMgr.listBlockedSuccessors w
    of nil => ""
    |  ws  =>
        concat (
            List.map (
                fn (r, w') => ( 
                   " v " ^ r ^ 
                   " w " ^ Int.toString (Node.getId w ) ^ 
                   " w"  ^ Int.toString (Node.getId w') ^ "\n" 
            ) ws
        )

This function is concatenating all the w'possible and then:

fun af w = print( getBlocked(w) )

With af I'm able to display one node. And then in the final code I'm calling

app af ( Nodestore.listNodes() ) 

And my function app will call af on all the Node of my listNodes().

So as I said, this code is working but when the list start to be huge, it is not usable anymore... My guess is that the concat is definitely not a good idea, so I would like to replace it and be able to display directly each w' successor of each w. But unfortunately, I'm quite a newbie in SML and I don't know how to do it...

Thanks in advance for your help :)

Best Regards.


Solution

  • It's a bit unclear what you really want, but from what I understand, the following should solve your problem:

    fun displayBlocked w =
      let
        fun renderW (r, w') =
          " v " ^ r ^
          " w " ^ Int.toString (Node.getId w ) ^
          " w"  ^ Int.toString (Node.getId w') ^ "\n"
      in
        case BlockingMgr.listBlockedSuccessors w
        of nil => ()
        |  ws  => List.app (fn w => print (renderW w)) ws
      end
    

    With display count:

    fun displayBlocked w =
      let
        fun renderW (r, w') =
          " v " ^ r ^
          " w " ^ Int.toString (Node.getId w ) ^
          " w"  ^ Int.toString (Node.getId w') ^ "\n"
    
        fun renderAndInc (w, count) =
          (
            print (renderW w);
            count + 1
          )
      in
        case BlockingMgr.listBlockedSuccessors w
        of nil => 0
        |  ws  => List.foldl renderAndInc 0 ws
      end