0

I am super new to sml. I am trying to write a simple code that takes an array of 5 positions with certain numbers and returns the length of the smallest subarray that contains all numbers. However I am getting many error messages that I cannot find in Google. Can anyone help me? The code is the following

 fun Min x y = if x>y then return y else return x
    local
        val a = Array.array (3,0)
        val cordela = Array.array(5,0)
        val k=0
        val front=0
        val tail=0
        val min=5
        update(cordela,0,1)
        update(cordela,1,3)
        update(cordela,2,3)
        update(cordela,3,2)
        update(cordela,4,1)
    in   
        fun loop front = 
            case k>3 of
                if sub(a,sub(cordela,front)-1) = 0 then k=k+1 else()
                update(a,sub(cordela,front)-1),sub(a,sub(cordela,front)-1)+1)
                front = front +1
            | 
                min= Min (front-tail) min
                if sub(a,sub(cordela,front)-1) = 0 then k=k-1 else()
                update(a,sub(cordela,front)-1),sub(a,sub(cordela,front)-1)-1)
                tail=tail+1

            if 5>front then loop front+1 else min
    end 

The error messages that I get are:

pl2.sml:16.13-16.15 Error: syntax error: replacing  OF with  LBRACKET
pl2.sml:18.36 Error: syntax error: inserting  LPAREN
pl2.sml:20.4 Error: syntax error: replacing  BAR with  EQUALOP
pl2.sml:22.5 Error: syntax error: inserting  LPAREN
pl2.sml:26.4 Error: syntax error: inserting  LPAREN
pl2.sml:27.2 Error: syntax error found at END

Edit: I am trying to write this code in sml. It is written in c++

while(front < N){
        if( k < K ){
            if ( e[cordela[front]-1] == 0 ) k += 1;
            e[cordela[front]-1] +=1;
            front++ ;
        }
        else{
            min = MIN(front - tail ,min);
            if ( e[cordela[tail]-1] ==1 ) k -= 1;
            e[cordela[tail]-1] -= 1;
            tail++;
        }
    }
sshine
  • 15,635
  • 1
  • 41
  • 66
  • SML/NJ error messages can be opaque. Note that you are missing a matching `else`, which are not optional in sml. – John Coleman Mar 29 '19 at 10:46
  • @JohnColeman I fixed the else statements but still the errors come up a bit different –  Mar 29 '19 at 12:29
  • Your `case` makes no sense (where are the `=>` ?). More generally, you seem to be trying to write Java-like code in SML. You are thinking way too imperatively rather than functionally. Also -- why are you using `local` rather than `let`? – John Coleman Mar 29 '19 at 13:49
  • @JohnColeman Thank you , what improvements should I have made in this code in order to work in ML –  Mar 29 '19 at 14:40
  • It isn't at all clear what you are trying to do. What is the type of the function that you are trying to write? The code is very verbose for SML, but since I don't really know what you are trying to do, I can't make concrete recommendations. There is a lot of confusion on your part about the basic semantics of SML. For example. `if sub(a,sub(cordela,front)-1) = 0 then k=k+1 else()` won't type check. since the type of `k=k+1` is boolean (it doesn't replace `k` by `k+1`, instead it compares `k` and `k+1`, evaluating to `false`), but the type of the `()` at the end is `unit`, not boolean. – John Coleman Mar 29 '19 at 16:47
  • @JohnColeman Please see the edit –  Mar 29 '19 at 21:47
  • "I am trying to write this code in sml. It is written in c++" --- why? Just write SML code in SML. You are trying to write imperative code in a functional language, Forget about C++. It isn't really relevant here. Also -- you never clearly explained just what it is that you are trying to do. What is the *type* of the function that you are trying to write? – John Coleman Mar 29 '19 at 23:44
  • @JohnColeman I am trying to write a function that finds the length of the smallest subarray that contains all the elements that are on the big array. Ex : 1 2 2 3 2 2 2 3 1 Answer : 3 –  Mar 30 '19 at 10:12
  • Are you sure that you mean array, rather than list? Also, when I was asking for type, I was looking for something like `int list -> int` – John Coleman Mar 30 '19 at 10:27
  • @JohnColeman It could be both , The numbers are given as input from a file –  Mar 30 '19 at 10:29
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/190954/discussion-between-maverick98-and-john-coleman). –  Mar 30 '19 at 10:41

1 Answers1

1

As John Coleman says, SML/NJ will not give very helpful error messages. You could try and install Moscow ML instead, since it gives better error messages. Unfortunately, there are some things wrong with this code at a syntactic level that makes it difficult for the compiler to give a meaningful error. Here are some hints to get the syntax right so that you can focus on the algorithm problems:

  • Don't use local, use let.
  • Match each ( with a ); you have too many )s.
  • Declare fun loop ... = ... inside let and in.
  • Once you've done that, a template for the function that solves your problem could look like:

    fun smallest_subarray (needles : Array.array, haystack : Array.array) =
        let
          val ... = ...
          fun loop ... = ...
        in
          if Array.length needles > Array.length haystack
          then ...
          else loop ...
        end
    

What if there's no solution to the problem, what will the function return? ~1? NONE?

If you're trying to convert a C++ program to SML, try and include the function part in such a way that it's obvious what identifiers are arguments to the function, and try to name them logically; I have no idea what cordela, e and k are, or if N is a function of the size of the input array, or a constant.

Since an idiomatic solution in SML uses recursion (the function calling itself) rather than iteration (while), you are dealing with both a non-trivial algorithm problem and another paradigm. Try instead to solve a similar, but simpler problem where the algorithm is more trivial and apply the recursion paradigm.

For example, try and write a function that finds the position of an element in a sorted array using binary search:

fun find x arr =
    let
      fun loop ... = ...
    in
      loop ...
    end

The loop function would take the search bounds (e.g. i and j) as argument and return either SOME i if x is found at position i, or NONE. You could extend this problem in the direction of your original problem by then trying to write a function that determines if an input array, needles, occurs in another input array, haystack, in the order given in needles. You could first assume that needles and haystack are sorted, and then assume that they're not.

sshine
  • 15,635
  • 1
  • 41
  • 66
  • As usual, your answers are very informative but still manage to be not so informative that they leave nothing for the student to complete. – John Coleman Apr 01 '19 at 13:28
  • @SimonShine I tried to solve the problem proposed at the end of your answer `fun find x arr= let val j=length arr fun loop i = if (x== sub(arr,i)) then return i else return loop i-1 in loop j end` Is this correct? –  Apr 02 '19 at 09:14
  • @maverick98: StackOverflow comments are not ideal for discussing partial solutions to other problems than what the original question was about. And no. :) – sshine Apr 02 '19 at 09:25