SOME([]) interpreted as 'z -> 'z option rather then 'z list option - smlnj

Hi im trying to write a simple function using the standard library
it should take the following argument
try = fn: 'a -> 'b list option
a_list = 'a list
and the defintion is the following:
fun all_answers try a_list =
let fun acc(SOME(a), SOME(b)) = SOME(b#a)
| acc(_,_) = NONE
in
List.foldl (fn(x,y) => acc(try(x), y)) SOME([]) a_list
end
and i get the following error:
hw3provided.sml:70.3-70.60 Error: operator and operand don't agree [tycon mismatch]
operator domain: 'Z list option
operand: 'Y -> 'Y option
in expression:
(List.foldl (fn (<pat>,<pat>) => acc <exp>)) SOME
C:\Program Files (x86)\SMLNJ\\bin\.run\run.x86-win32.exe: Fatal error -- Uncaught exception Error with 0
raised at ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
ive tried decomposing the function and the error seems to correspond to the use of SOME([]), if i use NONE instead it typechecks perfectly
I am at a total loss here
just incase its significant im using the sublime repl to run the script

figured out the solution but not really the problem
surround the SOME([]) with brackets (SOME([]))
just in case anybody else comes across the same issue

Related

Reason for Stream class can be used for 'first class loop'

Stream(1,2,3,4).map(_+10).filter(_%2==0).toList
I'm curious about the reason why above expression should be executed one element by one element without temporary output(first class loop). For example,
cons(11, Stream(2,3,4).map(_+10)).filter(_%2==0).toList
cons(12, Stream(3,4).map(_+10)).filter(_%2==0).toList
12 :: cons(13, Stream(4).map(_+10)).filter(_%2==0).toList
12 :: 14 :: List()
Since there is no extra command for changing order of executing.
I thought executing order would like this,
cons(11, Stream(2,3,4).map(_+10)).filter(_%2==0).toList
cons(11, cons(12, Stream(3,4).map(_+10))).filter(_%2==0).toList
cons(11, cons(12, cons(13, Stream(4).map(_+10)))).filter(_%2==0).toList
cons(11, cons(12, cons(13, cons(14, Empty))))).filter(_%2==0).toList
.
.
12 :: 14 :: List()
Because map command is lefter than filter command.
... while I'm writing this, I realize that there may be another rule:
'outer command first, inner command later'
and this 'outer -> inner' rule comes faster than 'left -> right' rule.
so, inner map command of below is slower than outer filter command of below.
cons(11, Stream(2,3,4).map(_+10)).filter(_%2==0).toList
Is my thinking right?
Because streams are lazy, each element is evaluated on an "as needed" basis. Consider the following example stream:
val es = Stream(2,3,4).map(x=>{println("add");x+10})
.filter(x=>{println("filt");x%2==0})
The first element is evaluated with the definition of the stream, but nothing else until you ask for it.
scala> es(0)
res314: Int = 12
scala> es(1)
add
filt
add
filt
res315: Int = 14
Think of it this way, when I asked for es(1) it "pulled" 3 through the map (adding 10) but it failed to get through the filter. Since we still didn't have the next es() element yet, we had to pull 4 through the map and this time it passed the filter step.

append if element in list

I'm trying to create a parser for program. For example,
I entered (what I want)
"(2+3)-4" it will become something like this "(minus, (plus, num 2, num 3),num 4)"
What I've done so far..
"(2+3)-4" I then split it and it becomes list Z = ["(","2","+","3",")","-","4"] then I compared if "-" is a member of Z, if true I append the element "-" into a new list ["-"]
I'm not sure if the way I'm doing is correct, I'm new to Er-lang and struggling quite a lot. If anyone is able to offer me some insight, thanks.
Consider the following, which returns a tuple-based representation of its input:
parse(Expr) ->
Elems = re:split(Expr, "([-+)(])", [{return,list}]),
parse(lists:filter(fun(E) -> E /= [] end, Elems), []).
parse([], [Result]) ->
Result;
parse([], [V2,{op,Op},V1|Tacc]) ->
parse([], [{Op,V1,V2}|Tacc]);
parse(["("|Tail], Acc) ->
parse(Tail, [open|Acc]);
parse([")"|Tail], [Op,open|TAcc]) ->
parse(Tail, [Op|TAcc]);
parse(["+"|Tail], Acc) ->
parse(Tail, [{op,plus}|Acc]);
parse(["-"|Tail], Acc) ->
parse(Tail, [{op,minus}|Acc]);
parse([V2|Tail], [{op,Op},V1|Tacc]) ->
parse(Tail, [{Op,V1,{num,list_to_integer(V2)}}|Tacc]);
parse([Val|Tail], Acc) ->
parse(Tail, [{num,list_to_integer(Val)}|Acc]).
The first function, parse/1, splits the expression along the + and - operators and parentheses, preserving these in the resulting list. It then filters that list to remove empty elements, and passes it with an empty accumulator to parse/2.
The parse/2 function has eight clauses, described below:
The first two handle the case when the parsed input list has been exhausted. The second of these handles the case where multiple elements in the accumulator need to be collapsed into a single tuple consisting of operator and operands.
The next two handle clauses parentheses. When we see an open parenthesis, we push an atom open into the accumulator. Upon seeing the matching close parenthesis, we expect to see an operation tuple and the atom open in the accumulator, and we replace them with just the tuple.
Clauses 5 and 6 handle + and - respectively. Each just pushes a {op,Operator} tuple into the accumulator, where Operator is either the atom plus or the atom minus.
The final two clauses handle values. The first one handles the case where the accumulator holds a value and an op tuple, which gets replaced with a full operation tuple consisting of the atom plus or minus followed by two num tuples each holding integer operands. The last clause just handles plain values.
Putting this in a module p, compiling it, and running it in an Erlang shell yields the following:
1> p:parse("2+3").
{plus,{num,2},{num,3}}
2> p:parse("(2+3)-4").
{minus,{plus,{num,2},{num,3}},{num,4}}

Fortran convert string to number

I want to have a subroutine that converts a contents of a numeric
string to a numeric type (int, real, double precision, real(real128)).
However I am getting an error when trying to use Class(*). The error
is shown below:
gfortran -o build/lib/larsa.o -c -ffree-form -g -J./build/lib lib/larsa.f
lib/larsa.f:1933.35:
Read (s, frmt, iostat=ios) num
1
Error: Data transfer element at (1) cannot be polymorphic unless
it is processed by a defined input/output procedure
lib/larsa.f:1935.32:
Read (s, *, iostat=ios) num
1
Error: Data transfer element at (1) cannot be polymorphic unless
it is processed by a defined input/output procedure
This is the subroutine I have written.
Subroutine converts_str_to_num &
( &
s, num, &
fmt, wrn &
)
Character (len=*), Intent (in) :: s
Character (len=*), Intent (in), Optional :: fmt
Class (*) :: num
Character (len=*), Intent (inout), Optional :: wrn
Integer :: ios
Character (len=65) :: frmt
!!$ Reads contents of s and puts value in i.
If (Present (fmt)) Then
frmt = "(" // Trim (fmt) // ")"
Read (s, frmt, iostat=ios) num
Else
Read (s, *, iostat=ios) num
End If
End Subroutine converts_str_to_num
To tidy up the comments, I'll provide an answer.
The error message is clear: you cannot have a polymorphic variable in an input/output list unless the list is processed by defined input/output. This is 9.6.3.5 in Fortran 2008. class(*) num is (unlimited) polymorphic.
Now, for polymorphic derived types you could define such a defined input/output procedure, but that counts as a lot of work and gfortran certainly doesn't (yet) support that notion. Also, you can't do this for intrinsic types. These factors mean you have to deal with non-polymorphic variables in the input list you have.
Of course, it's possible to use generics to avoid polymorphism, but the alternative (as it is for about everything polymorphic) is to use a select type construct. For simplicity, ignore the list-directed and explicit format cases:
select type (assoc => num)
type is (int)
Read (s, *, iostat=ios) assoc
type is (real)
...
type is (...)
class default
error stop "Oh noes!"
end select
I've used an associate name in the select type to address one part of your confusion. If you've just done
select type(num)
type is (int)
Read (s, *, iostat=ios) num
end select
to think that "now using num is fine: why?" that's because the num inside the construct is not the same as the num outside. Crucially, it isn't polymorphic but is the exact type matching the type is.

Calling a Clojure function with string inside swap?

The macro, transform!, as defined below seems to work for => (transform! ["foo" 1 2 3]). The purpose is to take in a list, with the first element being a string that represents a function in the namespace. Then wrapping everything into swap!.
The problem is that transform! doesn't work for => (transform! coll), where (def coll ["foo" 1 2 3]). I am getting this mystery exception:
#<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: Symbol>
The function:
(defmacro transform!
" Takes string input and update data with corresponding command function.
"
[[f & args]] ;; note double brackets
`(swap! *image* ~(ns-resolve *ns* (symbol f)) ~#args))
I find it strange that it works for one case and not the other.
Macros work at compile-time and operate on code, not on runtime data. In the case of (transform! coll), the macro is being passed a single, unevaluated argument: the symbol coll.
You don't actually need a macro; a regular function will suffice:
(defn transform! [[f & args]]
(apply swap! *image* (resolve (symbol f)) args)))
Resolving vars at runtime could be considered a code smell, so think about whether you really need to do it.
You're passing a symbol to the macro, namely coll. It will try to pull that symbol apart according to the destructuring statement [f & args], which won't be possible of course.
You can also use (resolve symbol) instead of (ns-resolve *ns* symbol).

Why does Scala's semicolon inference fail here?

On compiling the following code with Scala 2.7.3,
package spoj
object Prime1 {
def main(args: Array[String]) {
def isPrime(n: Int) = (n != 1) && (2 to n/2 forall (n % _ != 0))
val read = new java.util.Scanner(System.in)
var nTests = read nextInt // [*]
while(nTests > 0) {
val (start, end) = (read nextInt, read nextInt)
start to end filter(isPrime(_)) foreach println
println
nTests -= 1
}
}
}
I get the following compile time error :
PRIME1.scala:8: error: illegal start of simple expression
while(nTests > 0) {
^
PRIME1.scala:14: error: block must end in result expression, not in definition
}
^
two errors found
When I add a semicolon at the end of the line commented as [*], the program compiles fine. Can anyone please explain why does Scala's semicolon inference fail to work on that particular line?
Is it because scala is assuming that you are using the syntax a foo b (equivalent to a.foo(b)) in your call to readInt. That is, it assumes that the while loop is the argument to readInt (recall that every expression has a type) and hence the last statement is a declaration:
var ntests = read nextInt x
wherex is your while block.
I must say that, as a point of preference, I've now returned to using the usual a.foo(b) syntax over a foo b unless specifically working with a DSL which was designed with that use in mind (like actors' a ! b). It makes things much clearer in general and you don't get bitten by weird stuff like this!
Additional comment to the answer by oxbow_lakes...
var ntests = read nextInt()
Should fix things for you as an alternative to the semicolon
To add a little more about the semicolon inference, Scala actually does this in two stages. First it infers a special token called nl by the language spec. The parser allows nl to be used as a statement separator, as well as semicolons. However, nl is also permitted in a few other places by the grammar. In particular, a single nl is allowed after infix operators when the first token on the next line can start an expression -- and while can start an expression, which is why it interprets it that way. Unfortunately, although while can start a expression, a while statement cannot be used in an infix expression, hence the error. Personally, it seems a rather quirky way for the parser to work, but there's quite plausibly a sane rationale behind it for all I know!
As yet another option to the others suggested, putting a blank newline between your [*] line and the while line will also fix the problem, because only a single nl is permitted after infix operators, so multiple nls forces a different interpretation by the parser.