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...

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 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...

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...

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...

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...

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...

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 =...

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....

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...

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...

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 ...

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...

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...

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...

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...

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...

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...

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)

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));...

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

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)...

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...

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...

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) =...

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...

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 |...

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 [] _ =...

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...

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....

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...

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...

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...

(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 =...

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...

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...

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...

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...

exception,exception-handling,sml,smlnj,raise

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

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...

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) ...

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) => ... ...

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...

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....

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...

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....

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

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,...

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...

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

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....

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...

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...

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...

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...

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...