nested local declarations in ML of NJ - sml

hello everyone I have this snippet of the code:
local
helper(f, i, j) = local
fun NTimesF(f, n:int) =
if n = 1 then fn (x) => f(x)
else fn (x) => f(NTimesF(f, n - 1)(x));
in
if(i <= j) then NTimesF(f, i) :: helper(f, (i+1), j)
else []
end
in
fun compList f n = helper(f, 1, n);
end;
I need to write program which receives some function f and integer n and produce list of functions such as [f1, f2, ... fn] <- fn is the composition of the function n times but every time I receive an error:
- stdIn:1.1-2.9 Error: syntax error: deleting LOCAL ID LPAREN
stdIn:2.10-2.14 Error: syntax error: deleting COMMA ID COMMA
stdIn:2.16-2.25 Error: syntax error: deleting RPAREN EQUALOP LOCAL
stdIn:3.6-3.17 Error: syntax error: deleting FUN ID
stdIn:4.6-4.10 Error: syntax error: deleting IF ID
stdIn:4.15-4.22 Error: syntax error: deleting THEN FN
stdIn:4.27-4.31 Error: syntax error: deleting DARROW ID
stdIn:5.6-5.13 Error: syntax error: deleting ELSE FN
stdIn:5.16-5.22 Error: syntax error: deleting RPAREN DARROW ID
stdIn:6.8-7.8 Error: syntax error: deleting IN IF
stdIn:7.17-7.29 Error: syntax error: deleting THEN ID
stdIn:8.6-8.13 Error: syntax error: deleting ELSE LBRACKET RBRACKET
stdIn:9.8-11.5 Error: syntax error: deleting END IN FUN
it seems that my nested local declarations are wrong, can somebody please explain why?

There are two ways to define local functions and variables in SML: local ... in ... end and let ... in ... end.
The difference between local and let is that with local what comes between in and end are one or more variable or function declarations. With let what comes between in and end is an expression.
Unlike local, let is an expression and the value of a let expression is the value of the expression between in and end.
Since in your case you have an expression between in and end (and you want the function to evaluate to the result of that expression), you need to use let, not local.

Related

Could not infer type of parameter

I have created MyList abstract class to implement the list, the reason for not using already present list implementation is I am learning Scala and this was exercise for the same course. I am writing a zipWith function to create a new list with concatenation of individual items for example:
list 1: list = [1,2,3]
list 2: listOfStrings = ["Hello", "This is", "Scala"]
and I am expecting output like: [1-Hello, 2-This is, 3-Scala]
I wrote zipWith function as mentioned below:
override def zipWith[B, C](list: MyList[B], zip: (A, B) => C): MyList[C] = {
if(list.isEmpty) throw new RuntimeException("Lists do not have the same length")
else new Cons(zip(h, list.head), t.zipWith(list.tail, zip))
}
And I am trying to call this function using this statement:
println(list.zipWith[String, String](listOfStrings, (Int,String)=>_+"-"+_))
But I am getting an error:
I could not infer the type of the parameter $3 of expanded function:
($3, _$4) => _$3 + "-" + _$4.
Type for this variable is clearly mentioned as Int still I am getting this error. This could be solved using:
println(list.zipWith[String, String](listOfStrings, _+"-"+_))
I am not able to understand why earlier statement fails, even after giving the type for the required variable
The syntax (Int,String)=>_+"-"+_ doesn't mean what you think.
It represents a function taking two parameters with some name but unknown type: (Int: ???, String: ???) => _+"-"+_.
Thus the compiler is raising an error because it indeed have no clue about the types.
You should either:
write it with explicit variable names: (i: Int, s: String) => s"$i-$s". (Notice the usage of interpolation which is recommended over adding int and string),
or declare the function separately like this: val f: (Int, String) => String = _+"-"+_.
I think the compiler is confused on which variable to match each underscore. This explicit expression works for me:
println(list.zipWith[String, String](listOfStrings, (a:Int, b:String) => a+"-"+b))

Function in ocaml

I've tried to create a function that takes 2 arguments: a list of strings and the function String.contains and return o set formed by the strings that returns true in the function string.contains and I got the following error:
This expression has type S_String.t = Set.Make(String).t
but an expression was expected of type S_String.elt list
this is what I tried:
let f lista= List.fold_left(fun rez x -> if String.contains x 'e' then S_String.add x rez else rez) lista S_String.empty;;
List.fold_left takes the initial value as the second argument and the list as the third argument. You have them reversed.

Not typed empty list : Haskell

I just tried to write the simplest maybe function I could imagine in Haskell, and got this error message. And magically it only appears, when I try to evaluate myHead for an empty list. What did I do wrong?
module Main
where
myHead :: [a] -> Maybe a
myHead [] = Nothing
myHead (x:_) = Just x
main = do
print (myHead [])
When I run it from a file, I get this output :
main.hs:15:1: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘print’
prevents the constraint ‘(Show a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Show Ordering -- Defined in ‘GHC.Show’
instance Show Integer -- Defined in ‘GHC.Show’
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
... plus 22 others
...plus 12 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In a stmt of a 'do' block: print (myHead [])
In the expression: do { print (myHead []) }
In an equation for ‘main’: main = do { print (myHead []) }
<interactive>:3:1: error:
• Variable not in scope: main
• Perhaps you meant ‘min’ (imported from Prelude)
There's nothing wrong with myHead, you would have the same issue if you used:
main = do
print Nothing
The issue here is that Nothing and myHead [] have a polymorphic type Maybe a, for any a. Then, print is called to write that value. For that, print has to require that Maybe a is convertible to string: it does that by requiring Show (Maybe a), which in turn it requires Show a.
However, there is no universal instance of Show a: the compiler now needs to know what a is before it can convert that to string.
Note this
print (Just 3 :: Maybe Int) -- OK
print (Just id :: Maybe (Int->Int)) -- Not OK! Functions can not be printed
The solution is to use a concrete type for your code
main = do
print (myHead [] :: Maybe Int) -- or any other showable type

How can I convert a StringMap to a List in OCaml?

I am very new to OCaml and am trying to convert a StringMap to a List in OCaml.
The map was generated from a list previously.
let map = List.fold_left(<SOME CODE HERE, WHICH I AM OMITTING>
) StringMap.empty
in StringMap.fold(fun w c newlist -> (c,w)::newlist) map[]
The last line in the code above gives me the following error:
This expression has type StringMap.key list -> int StringMap.t
but an expression was expected of type
'a StringMap.t = 'a Map.Make(String).t
Please note: This code is typed into an ocamllex file (.mll) and I get this error when I try to execute the lexical analyser (.ml) file generated.
Why am I getting this error? How do I get my code to work?
Thanks!
StringMap.bindings will return a list of (key, value) pairs.
The error is telling you that the map value has type StringMap.key list -> int StringMap.t, which means that it's a function, not a map as you expected it. Furthermore, the function signature tells you what was missing in the previous expression to get a int StringMap.t as you expected: you need to add a parameter to the call to List.fold_left, of type StringMap.key list, which I suppose is a string list:
let map = List.fold_left(<SOME CODE HERE, WHICH I AM OMITTING>
) StringMap.empty string_list
Where string_list is the missing parameter: the list of keys used to build your map.

Standard ml function in datatype problem

I have to create a function about peano numbers defined as the following datatype:
datatype 'a peano = P of ('a -> 'a) * 'a -> 'a
val zero = P(fn (f, x) => x)
The function that I have to implement finds the succesive peano number of the peano parameter P(p). This is what I have written:
fun suc (P(p)) = case P(p) of P(fn(f,x)=>x) => P(fn(f,x)=>f(x));
The problem is that i get these errors:
stdIn:4.33-4.36 Error: syntax error: deleting FN LPAREN
stdIn:4.43 Error: syntax error found at RPAREN
I don't know what Im doing wrong. Please help!
There are a number of problems in this code. The one the compiler is whining about is that you have a function definition
fn (f,x) => x
on the left-hand side of a case arm, where only patterns are permitted.
Some other problems:
Redundant parentheses make the code hard to read (advice is available on removing them).
Your case expression is redundant; in the function definition
fun suc (P p) = ...
it should be possible just to compute with p without any more case analysis.
Since P carries a function, you will probably have an easier time if you write
fun suc (P f) = ...
and make sure that in the result, f is applied to a pair (as required by the datatype declarations).