recursion,functional-programming,sml

You can use an int ref as a mutable cell: val counter : int ref = ref 0 -- Some dummy recursive function for testing fun factorial n = if n < 1 then 1 else (counter := !counter + 1; n * factorial (n - 1)) You can use...

sockets,exception-handling,sml,smlnj,keyboardinterrupt

You've hit a pretty big limitation with Standard ML per se, which is that the standard language does not make any provisions for concurrent programming. And you need concurrency in this particular case. Luckily, you're using SML/NJ, which has some extensions that allow concurrency support — continuations. In SML/NJ, you...

Yes, they can, but the matched list won't be empty, so the result of the null function holds, i.e., [] :: [], which is equivalent to [[]], is not an empty list. No, that's syntactically invalid. However, it can be shortened to this: fun null [] = true |...

The sml command is intended to be used interactively. It sounds to me like you would be better off building a standalone executable from your program instead. There are a few options: If you are relying on SML/NJ extensions, or if you simply cannot use another ML implementation, you can...

You can use the LambdaCase language extension and perform {-# LANGUAGE LambdaCase #-} ... f $ \case A a1 a2 -> ... as per your example. You can read more about it in GHC's documentation...

fib n - 1 is equivalent to (fib n) - 1, not fib (n - 1). So the line fib n = (fib n - 1) + (fib n - 2) calls fib n again, causing infinite recursion. To fix the problem, add parentheses....

function,functional-programming,sml,smlnj,ml

It's simple indeed: an identifier cannot start with an underscore. So _a is parsed as if you had written _ a, in accordance with the usual maximal munch rule for lexical syntax. Edit: Extra tip: Your function does not have the type 'a list -> 'b, because help returns a...

parsing,grammar,sml,yacc,context-free-grammar

Index has an empty production. Now consider: Exp : ID | ID Index Which of those applies? Since Index is allowed to be empty, there is no context in which only one of those is applicable. The parser generator you are using evidently prefers to reduce an empty INDEX, making...

arrays,list,tuples,time-complexity,sml

The sml function has O(1) complexity, so feel free to use it! e.x. `fun isTrue (n,tup) = if Array.sub(tup,n) then true else false;` As far as the tuple is concerned, you can only use a specific number, not a variable in a tuple. e.x. fun isTrue (n,tup) = if #2...

You can parameterize the type in the signature. But composing monoids then becomes odd or impossible. Haskell solves this using type classes, which you can emulate in SML with functors, but the syntax is heavy (as you've noticed). signature MONOID = sig type 'a monoid val neutral : 'a monoid...

In Standard ML, type variables are prefixed with a single quote: datatype 'alpha susp = $ of 'alpha ...

Wild cards are used for pattern matching only. They can not be used as expressions as they do not evaluate to a value.

While there isn't a built in direct conversion function, you could use Array.foldr to quite easily construct a corresponding list: fun arrayToList arr = Array.foldr (op ::) [] arr Example: - val arr = Array.fromList [6, 3, 5, 7]; val arr = [|6,3,5,7|] : int array - val ls =...

exception,exception-handling,sml,smlnj,raise

The exception was actually defined inside a module, so I had to call it like MyModule.MyException msg.

Let me know if the explanations in the code make sense. fun example (xss, yss) = case (xss, yss) of (* If the 1st list is empty, then the result is an empty list. *) ([], _) => [] (* If the 2nd list is empty, then the result is...

You can make them constructors: datatype Op = APPEND | ... and then tokenize your stream datatype Token = Op of Op | Id of string | ... and then your pattern match can be case (tts t2) of (other, APPEND) => ... ...

In SML, datatypes declarations whose arguments are eqtypes are eqtypes. So you can instead just use fun valid(x1, x2, x3) = not(x1 = x2) andalso not(x1 = x3) andalso not(x2 = x3) ...

First you don't need to create a length function as length is a build-in function that returns an int representing the elements of an 'a list. One more thing, you raise an exception c4 in your function drop. Then you should also include that in the beginning of your program....

You are probably using an outdated version of Moscow ML. Try version 2.10 or later, which has String.isSubstring.

recursion,functional-programming,sml,smlnj,continuations

Continuations simply treat "what happens next" as first class objects that can be used once unconditionally, ignored in favour of something else, or used multiple times. To address what Continuation Passing Style is, here is some expression written normally: let h x = f (g x) g is applied to...

There's probably no way to do this portably but in Poly/ML you can find out whether a value, or anything else, is defined using PolyML.globalNameSpace. To test for a value (e.g. a function) use #lookupVal PolyML.globalNameSpace This takes a name and returns a option type which is SOME if the...

sorting,sml,largenumber,selection-sort

IntInf is the name of a module, the type is named IntInf.int. Alas, your code somewhat simplified: fun selectsort([a]) = [a] | selectsort(x::y::t : IntInf.int list) = if y < x then y::x::selectsort(t) else x::selectsort(y::t) Note however that IntInf is an optional module that is not available on all implementations....

string,list,find,sml,substitute

You're making this way too complicated. This first function looks up a string in the first list: fun lookup ((a,b)::xs) v = if v = b then a else lookup xs v | lookup nil v = v; And this one just runs recursively on both elements in the second...

The stack is passed as an additional argument to parse. You'll want to pass the accumulated RPN as well. Although the shunting-yard algorithm is usually presented as an algorithm for converting infix to postfix notation, it is actually just a parsing algorithm; you can directly evaluate infix expressions or create...

(Thanks to bgates from #sml for pointing me in the right direction here) Two problems with the above. Firstly, I had a typo in the constructor name in the call to Socket.select. ... rds = descs [server], wrs = descs [], (* `wrs` instead of `wds` here *) exs =...

I'm not entirely sure what the function you posted does, but it almost certainly won't unzip a list of 2-tuples for you. It seems to expect 3-tuples, and does some de-referencing/concatenation to boot. How did you find it? If you want a function that takes a list of 2-tuples and...

Your Server functor does multiple arguments via currying. That does not work in plain SML, because it does not have higher-order functors (which SML/NJ supports as a non-standard extension). You need to use uncurried form, by introducing an auxiliary structure, like you would use a tuple or record in the...

It turns out that an ArraySlice of Word8s is not the same thing as a Word8ArraySlice. In order to get the latter from a string, you need to call packString with an appropriate array. I decided to use Vectors instead, which meant that I could do Word8VectorSlice.full (Byte.stringToBytes res) to...

string,types,sml,typeconverter,custom-data-type

You need to implement a function that can print all variants of etype by recursing into each value. You also need a helper function for printing basicType values, bot it does not need to be recursive but instead act as the base case in your recursion. Both of them need...

What you have to do is use the two strategies, first try reducing the numbers via ADD, then reduce the numbers via MULT, but sequentially. In order to do this you need to provide a custom failure continuation (k) to the result of the first chosen strategy. If that strategy...

Considering that the fold function, the list datastructure and tail-recursion are intertwined, you can come up easily with a fold-based solution if you already have a tail-recursive solution. The problem of evaluating a polynom can be solved using a recursive function that implements horners method: fun eval [] _ =...

You need to put parentheses around the block and use semicolons to separate the individual expressions within it: fun fact 0 = 1 | fact x = (print (Int.toString x); x * fact (x-1)); Note that there's no need to put parentheses around x just to call a function on...

functional-programming,sml,currying

The root of the problem is that for this to work, the type of the folded function would have to change as it's folded through the list, and this (hopefully obviously) isn't possible. The "circularity" in (fn (p, f') => f' p) comes from the fact that the type of...

Your second case is wrong; you want fun flipAlternate(nil) = nil | flipAlternate([x]) = [x] | flipAlternate(x::y::xs) = y::x::flipAlternate(xs); SML is looking at the second case and concluding flipAlternate :: 'z list list -> 'z list which isn't compatible with the recursion in your third case. Edit: It knows the...

This code runs in PolyML 5.2: fun sum_pairs (l : (int * int) list) = if null l then [] else ((#1 (hd l)) + (#2 (hd l))) :: sum_pairs(tl l) (* ------------^-------------^ *) The difference from yours is subtle, but significant: (#1 hd(l)) is different from (#1 (hd l));...

When you see an error of the form: operator domain: <type1> operand : <type2> then it is saying that it is expecting something of type <type1>, but you are giving it something of type <type2>. In your case, get_nth is expecting a tuple, where the first element is a list...

You are correct, you need to traverse the tree, which can be elegantly achieved in SML by using pattern matching. You will want to case on the input tree, if it is Empty then simply return Empty. If it is a Node, then you will want to recursively convert the...

If a structure implements MERGEABLE_QUEUE, it provides a function that takes a pair of queues of arbitrary type (as long as the two queues have the same type as each other) and produces a new queue. In particular, it can take two int queues and produce another int queue (and...

parameters,pattern-matching,sml

Generally speaking, you don't check for this, because start=ziel is not a pattern -- patterns are (for the most part) values or special patterns like _ or variable names, while start = ziel is an expression that is not fully evaluated. Instead, pattern match to extract start and ziel, and...

The Word library has xor. - Word.xorb(0wxAAAA, 0wxAAA0); val it = 0wxA : word ...

There are two problems here: the first is that in the last line, you are asking for the sum of two lists with +; the second is that you are returning an int in one branch of the if, and a list in the other. The first problem just looks...

list,recursion,functional-programming,sml

I'm using 3 functions to find the largest number in a list and print its length. Decompose your goal in simpler steps: find the largest number in a list and print its length You may already see that this is not what you are doing. Your algorithm does the...

SML/NJ supports so called or-patterns: datatype X = A | CA | CB | D fun foo (A | CA | CB) = "A" | foo _ = "else" That's the most you can do, though. There's no feature to partially match a datatype constructor name, i.e., your C_ syntax....

sml,string-concatenation,nested-lists

There is a function concat : string list -> string in the String structure in the Basis Library, which happens to be at the top level. Therefore, you can define your function: val concatEach = map concat It is going to have type string list list -> string list, which...

The structure-level equivalent to include is open: structure Foo1 = struct val val1 = "val1" end structure Foo2 = struct val val2 = "foo2" end structure Foo = struct open Foo1 open Foo2 end ...

It is broken because as specified, it cannot be applied to structures that have transparent type components. For example: signature S = sig type t; type u = int end signature T = sig structure A : S structure B : S sharing A = B end would already be...

The function (fn x => fn y => x) is the constant function. It takes two arguments (x and y) and always returns the first argument (i.e. x). This function is applied to two arguments in all three functions a, b and c: In a the constant function is applied...

Caveat: I am unfamiliar with ML-Lex The syntax for Real.fromString is incorrect. It is a curried function and the call to getOpt should read: getOpt(Real.fromString yytext, 0.0) Example code: - getOpt(Real.fromString "1.0", 0.0); val it = 1.0 : real - getOpt(Real.fromString "a", 0.0); val it = 0.0 : real ...

The trouble is, that your reader (subtly) violates the semantics for readers. In this case, StringCvt.skipWS assumes, that if it calls stream_rdr s, and gets a SOME (c, s') back, then the original s remains unmodified. That is, it can try to read a character from the character source until...

As you mentioned, the function use has type string -> unit. This means it takes a string and returns unit. When you do use test.sml, you are not giving it a string. You need to do use "test.sml" (notice the quotes)

You are getting into problems because the then branch of the if expression is trying to do something which doesn't make sense: x = [] You can't re-assign values to already bound identifiers in Standard ML, although you can achieve mutability using refs, but they're not needed in this case....

python,haskell,functional-programming,ocaml,sml

One option is to use inductive graphs, which are a functional way of representing and working with arbitrary graph structures. They are provided by Haskell's fgl library and described in "Inductive Graphs and Funtional Graph Algorithms" by Martin Erwig. For a gentler introduction (with illustrations!), see my blog post Generating...

Try executing gcc -v -x c -E - in your terminal. This will print out the header file search path that your C compiler is using. I get something like: #include "..." search starts here: #include <...> search starts here: /Users/ml9951/include . /usr/local/include /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.1.0/include /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include /usr/include /System/Library/Frameworks (framework directory)...

Not the most efficient solution, but this should solve the problem: datatype ttree = node of string*ttree list*string | leaf of string*string*string val l = ["<root>", "<a3>", "<b2>","Father","</b2>", "<b3>","Mother","</b3>", "</a3>", "<a1>", "<ffx>","AAA","</ffx>", "</a1>"] (*listToTree(l) = string list to ternary tree*) fun listToTree(l : string list) : ttree = let (*isLeaf(s1,...

You can always raise an exception: fun last [] = raise Empty | last (x::xs) = last' x xs fun last' x [] = x | last' _ (x::xs) = last' x xs Another option (if you would pardon the pun): fun last [] = NONE | last (x::xs) =...

There are no statements in ML, only expressions. Even A;B is an expression, which evaluates A and B and whose result is the result of B. Consequently, the result of your first 3 if-expressions is just thrown away. Also, variables are variables in the true math sense, so they are...

fun toInt [] = 0 | toInt (x :: xs) = x + 10 * (toInt xs) To compute the right number out of a list of digits [a0, a1, a2, a3, ...] you just need to compute the sum a0 + a1*10 + a2*10*10 + a3*10*10*10 + .... Then...