Here's the situation:
In a library:
export fctn( simple int m )
...
In the calling code:
type Test
int n
inst = Test.new( n = 1 )
y = Library.fctn( inst.n )
...
This produces an error message that the function is being called with a "series int" when it must be called with a "simple int".
I may be missing something here, and it may be dealing with the simple input to the function. There were no errors when I avoided the object approach.
Related
This is my program:
modify :: Integer -> Integer
modify a = a + 100
x = x where modify(x) = 101
In ghci, this compiles successfully but when I try to print x the terminal gets stuck. Is it not possible to find input from function output in Haskell?
x = x where modify(x) = 101
is valid syntax but is equivalent to
x = x where f y = 101
where x = x is a recursive definition, which will get stuck in an infinite loop (or generate a <<loop>> exception), and f y = 101 is a definition of a local function, completely unrelated to the modify function defined elsewhere.
If you turn on warnings you should get a message saying "warning: the local definition of modify shadows the outer binding", pointing at the issue.
Further, there is no way to invert a function like you'd like to do. First, the function might not be injective. Second, even if it were such, there is no easy way to invert an arbitrary function. We could try all the possible inputs but that would be extremely inefficient.
Suppose that we have an object which has some properties of type proc:
type
x = object
y: proc(a,b:int)
proc myproc(a,b:int) =
echo a
var tmp = new x
tmp.y = myproc # I want to insert initial value in this line for example a = 1
tmp.y(5)
How can I insert initial values in the specified line, and not anywhere else?
Thank you in advance
As far as I know it's not possible to do what you want without other modifications, because you have specified y to be a proc receiving two parameters. So whatever you assign to it, the compiler is always going to expect you to put two parameters at the call site.
One alternate approach would be to use default values in the proc definition:
type
x = object
y: proc(a: int = 1, b: int)
proc myproc(a,b: int) =
echo(a, " something ", b)
var tmp = new x
tmp.y = myproc
tmp.y(b = 5)
The problems with this solution are of course that you can't change the value of a at runtime, and you are forced to manually specify the name of the parameter, otherwise the compiler is going to presume you are meaning the first and forgot to specify b. Such is the life of a non dynamic language.
Another approach is to define the proc as having a single input parameter, and then using an anonymous proc or lambda to curry whatever values you want:
type
x = object
y: proc(a: int)
proc myproc(a,b: int) =
echo(a, " something ", b)
var tmp = new x
tmp.y = proc (x: int) = myproc(1, x)
tmp.y(5)
If you were to use the sugar module, as suggested in the docs, the assignment line could look like:
tmp.y = (x: int) => myproc(1, x)
How do we do runtime constant in forward definition/declaration by any way around (tried hard not work on using let)
let n :int
proc m : int =
let i=1
var u=n+i
n=m()
error for this or for other varied ones:
Error: 'let' symbol requires an initialization
Error: redefinition of 'n'; previous
... etc
Please solve it out, thanks before
It's hard to say what you are trying to do with this code, a let variable is treated as a constant, so it can't be modified, but presumably your intent is to use the variable as a sort of counter to increase itself and presumably reassign n multiple times by calling m()? If you remove the n from the proc you can write the code like:
proc m : int =
let i=1
var u=0+i
let n :int = m()
So if you actually want n to be mutable, there's no problem using a var:
var n :int
proc m : int =
let i=1
var u=n+i
u
n=m()
echo n
Note that I had to add u as a last line to the m proc, because otherwise you were returning nothing and the assignment to n would always be zero, which is the default value for the implicit result variable inside a proc that returns something. You can verify this by repeating the n=m() assignment before the last echo.
Sometimes one wants to write bindings for some C code using ocaml modules as interface or optimize some method of an object in C. But one can't define the external function before the object because it needs the type of the object and one can't define the object because it needs to call the external function.
One solution is to use recursive modules but that easily tripples the source size and becomes awfully unreadable. The external functions also enter the modules namespace and need to be hidden again. So what is a shorter, more readable solution?
I figured out how to use first class modules to define an external function directly inside an objec. First one needs an module type to be used by the first class module. This is generic and can be used for any kind of external function over and over:
module type External = sig
type e
val stub : e
end
after that once can declare external functions like this:
class c =
let ext = (module struct
type e = c -> unit
external stub : c -> unit = "stub"
end : External with type e = c -> unit)
in
object(self:'self)
method as_c = (self :> c)
method foo =
let module E = (val ext)
in
E.stub self#as_c
end
or even more local within the method itself as:
class c = object(self:'self)
method as_c = (self :> c)
method foo =
let module E = (val (module struct
type t = c -> unit
external stub : c -> unit = "stub"
end) : External with type t = c -> unit)
in
E.stub self#as_c
end
Note: the as_c method avoids the (open) self type getting closed or escaping its scope.
I've been trying to run this function :
let insert_char s c =
let z = String.create(String.length(s)*2 -1) in
for i = 0 to String.length(s) - 1 do
z.[2*i] <- s.[i];
z.[2*i+1] <- c;
done;
z;;
print_string(insert_char("hello", 'x'));;
However the interpreter returns a type error at the last line "type is string * char" and it expected it to be string. I thought my function insert_char created a string. I don't really understand, thanks.
You define your function as a curried function, but you're calling it with a pair of values. You should call it like this:
insert_char "hello" 'x'
OCaml doesn't require parentheses for a function call. When two values are placed next to each other with nothing between, this is a function call.
The syntax of function application in OCaml is f arg1 arg2, not f(arg1, arg2). So it would be print_string (insert_char "hello" 'x').
(Once you fix that you'll discover that your code has other problems, but that is unrelated to your question.)