This expression has type 'a -> 'a array array but an expression was expected of type 'b array - dynamic

How is it possible to correctly manipulate a matrix in Ocaml?
What am I missing here, when assigning a value to a position on the matrix?
let dynamic arraymoedas valor len =
let arrayAux = Array.make_matrix (len+1) (len+1) in
for i=0 to len+1 do
arrayAux.(i).(0)=0;
done;
for j=0 to valor+1 do
arrayAux.(0).(j)= max_int
done;
for i=1 to len+1 do
for j=1 to len+1 do
if(arraymoedas.(i-j) > j) then
arrayAux.(i).(j) = arrayAux.(i - 1).(j)
else
arrayAux.(i).(j) = min (1+arrayAux.(i).(j-arraymoedas.(i - 1))) arrayAux.(i-1).(j)
done;
done;
!arrayAux
Error:
File "Novo_func.ml", line 38, characters 8-16:
38 | arrayAux.(i)(0)=0;
^^^^^^^^
Error: This expression has type 'a -> 'a array array
but an expression was expected of type 'b array

As identified in the comments, there are three issues with the code you've written.
Primarily, you're not using Array.make_matrix properly. This function has type int -> int -> 'a -> 'a array array. You've only supplied the dimensions, but not a default value. When you do this, you get back a function that takes in the default value and returns an array of arrays.
Secondly, when modifying the values in an array, use <- instead of =. Rather than arrayAux.(0).(j) = max_int you want to use arrayAux.(0).(j) <- max_int.
Thirdly, at the end of your dynamic function, you're using the ! operator to deref arrayAux. The problem with this is that arrayAux is not a reference. This will cause a compiler error due to a type mismatch.

Related

Implementing map & min that takes the tables.keys iterator as argument in Nim

I would like to define overloads of map and min/max (as originally defined in sequtils) that works for tables.keys. Specifically, I want to be able to write something like the following:
import sequtils, sugar, tables
# A mapping from coordinates (x, y) to values.
var locations = initTable[(int, int), int]()
# Put in some random values.
locations[(1, 2)] = 1
locations[(2, 1)] = 2
locations[(-2, 5)] = 3
# Get the minimum X coordinate.
let minX = locations.keys.map(xy => xy[0]).min
echo minX
Now this fails with:
/usercode/in.nim(12, 24) Error: type mismatch: got <iterable[lent (int, int)], proc (xy: GenericParam): untyped>
but expected one of:
proc map[T, S](s: openArray[T]; op: proc (x: T): S {.closure.}): seq[S]
first type mismatch at position: 1
required type for s: openArray[T]
but expression 'keys(locations)' is of type: iterable[lent (int, int)]
expression: map(keys(locations), proc (xy: auto): auto = xy[0])
Below are my three attempts at writing a map that works (code on Nim playground: https://play.nim-lang.org/#ix=3Heq). Attempts 1 & 2 failed and attempt 3 succeeded. Similarly, I implemented min using both attempt 1 & attempt 2, and attempt 1 failed while attempt 2 succeeded.
However, I'm confused as to why the previous attempts fail, and what the best practice is:
Why does attempt 1 fail when the actual return type of the iterators is iterable[T]?
Why does attempt 2 fail for tables.keys? Is tables.keys implemented differently?
Is attempt 2 the canonical way of taking iterators / iterables as function arguments? Are there alternatives to this?
Attempt 1: Function that takes an iterable[T].
Since the Nim manual seems to imply that the result type of calling an iterator is iterable[T], I tried defining map for iterable[T] like this:
iterator map[A, B](iter: iterable[A], fn: A -> B): B =
for x in iter:
yield fn(x)
But it failed with a pretty long and confusing message:
/usercode/in.nim(16, 24) template/generic instantiation of `map` from here
/usercode/in.nim(11, 12) Error: type mismatch: got <iterable[(int, int)]>
but expected one of:
iterator items(a: cstring): char
first type mismatch at position: 1
required type for a: cstring
but expression 'iter' is of type: iterable[(int, int)]
... (more output like this)
From my understanding it seems to say that items is not defined for iterable[T], which seems weird to me because I think items is exactly what's need for an object to be iterable?
Attempt 2: Function that returns an iterator.
I basically copied the implementation in def-/nim-itertools and defined a map function that takes an iterator and returns a new closure iterator:
type Iterable[T] = (iterator: T)
func map[A, B](iter: Iterable[A], fn: A -> B): iterator: B =
(iterator: B =
for x in iter():
yield fn(x))
but this failed with:
/usercode/in.nim(25, 24) Error: type mismatch: got <iterable[lent (int, int)], proc (xy: GenericParam): untyped>
but expected one of:
func map[A, B](iter: Iterable[A]; fn: A -> B): B
first type mismatch at position: 1
required type for iter: Iterable[map.A]
but expression 'keys(locations)' is of type: iterable[lent (int, int)]
proc map[T, S](s: openArray[T]; op: proc (x: T): S {.closure.}): seq[S]
first type mismatch at position: 1
required type for s: openArray[T]
but expression 'keys(locations)' is of type: iterable[lent (int, int)]
expression: map(keys(locations), proc (xy: auto): auto = xy[0])
which hints that maybe tables.keys doesn't return an iterator?
Attempt 3: Rewrite keys using attempt 2.
This replaces tables.keys using a custom myKeys that's implemented in a similar fashion to the version of map in attempt 2. Combined with map in attempt 2, this works:
func myKeys[K, V](table: Table[K, V]): iterator: K =
(iterator: K =
for x in table.keys:
yield x)
Explanation of errors in first attempts
which hints that maybe tables.keys doesn't return an iterator
You are right. It does not return an iterator, it is an iterator that returns elements of the type of your Table keys. Unlike in python3, there seems to be no difference between type(locations.keys) and type(locations.keys()). They both return (int, int).
Here is keys prototype:
iterator keys[A, B](t: Table[A, B]): lent A
The lent keyword avoids copies from the Table elements.
Hence you get a type mismatch for your first and second attempt:
locations.keys.map(xy => xy[0]) has an incorrect first parameter, since you get a (int, int) element where you expect a iterable[A].
Proposals
As for a solution, you can either first convert your keys to a sequence (which is heavy), like hola suggested.
You can directly rewrite a procedure for your specific application, mixing both the copy in the sequence and your operation, gaining a bit in performance.
import tables
# A mapping from coordinates (x, y) to values.
var locations = initTable[(int, int), int]()
# Put in some random values.
locations[(1, 2)] = 1
locations[(2, 1)] = 2
locations[(-2, 5)] = 3
func firstCoordinate[X, Y, V](table: Table[(X, Y), V]): seq[X] =
result = #[]
for x in table.keys:
result.add(x[0])
let minX = locations.firstCoordinate.min
echo minX
This is not strictly adhering your API, but should be more efficient.

Time Warping Variable Initialization?

In the following simple for loop we create an array (#a) by incrementing a typeless variable ($n):
my #a = do for 1..3 {
state $n;
$n.^name, $n++;
}
say #a;
The result is "kind of" expected:
[(Any 0) (Int 1) (Int 2)]
And I say "kind of" because I've expected as the first value of $n the "undefined" value (Any).
It is like, after the first value is produced (Any) and as we increment the $n (after the first increment of $n we have a casting to an Int) there is also some time warping event in the assignment and we get also the first value to change. So we end up having the first value as 0 (zero).
Can somebody explain the exact mechanism of this behaviour?
see Any.pm6#L519, the candidate
multi sub postfix:<++>(Mu:U $a is rw) { $a = 1; 0 }
is used.
There are some another candidates for undefined values, you can try
my Bool $x;
dd $x++; #Bool::False
my Num $y;
dd $y++; #0e0

Elm specify number to me Int

I am trying to see if length of a given list equals some number. However == expects two numbers not Int, so even when I type (==) 1 type is still number -> Bool so finally when I pipe in result of lenght I get compilation error:
-- TYPE MISMATCH ---------------------------------------------------------- REPL
This function cannot handle the argument sent through the (|>) pipe:
4| List.length |> ((==) 1)
^^^^^^
The argument is:
List a -> Int
But (|>) is piping it to a function that expects:
number
Hint: Only Int and Float values work as numbers.
So how can I specify that my constant is an Int as opposed to number variable?
I think you might be overthinking this, checking for equality is as straight forward in Elm as in other languages.
myList = [1, 2, 3]
List.length myList == 3 // True
If you do want to use the (==) function, in case you're doing currying or for other reasons
List.length myList |> (==)
And then you could either store that as a variable or invoke it right away
List.length myList |> (==) 3 // True
OR
lengthChecker = List.length myList |> (==)
lengthChecker 3 // True
But I would say it's better to stick to the simple version of just doing the check with ==.
Just to expand on why your attempt wasn't compiling, the signature for (==) is (==) : a -> a -> Bool meaning it's a function that takes one argument, a, and returns a function that takes one argument, a and returns a Bool. So in your case ((==) 1) is a function that wants a number. When you do List.length |> ((==) 1) you're trying to call that function that expects a number with the List.length function itself.
Use >> to compose functions.
isLengthOne = List.length >> ((==) 1) is a function that checks that the length of a list is 1.
|> pipes the output of one statement to the input of the next.
So aList |> List.length |> ((==) 1) would check aList.

Using named function declaration instead of anonymous function in Elm

In the REPL, if I use
> String.filter (\char -> char /= '-') "800-555-1234"
I get the result:
"8005551234" : String
as expected.
But if instead of the anonymous function I use a named function declaration like this:
> String.filter (isKeepable char = char /= '-') "800-555-1234"
I get this error:
-- SYNTAX PROBLEM -------------------------------------------- repl-temp-000.elm
The = operator is reserved for defining variables. Maybe you want == instead? Or
maybe you are defining a variable, but there is whitespace before it?
3| String.filter (isKeepable char = char /= '-') "800-555-1234"
^
Maybe <http://elm-lang.org/docs/syntax> can help you figure it out.
This seems odd to me, since the function declaration itself is an expression that returns a function object:
> isKeepable char = char /= '-'
<function> : Char -> Bool
So why can't that function reference be passed to filter like any expression that evaluates to a function?
Named function declarations are only valid at the top level or in a let clause. Try this instead:
> let isKeepable char = char /= '-' in String.filter isKeepable "800-555-1234"

How to Compare Types for Equality?

I attempted to compare a String and String, expecting True.
Idris> String == String
Can't find implementation for Eq Type
Then I expected False when comparing a String to a Bool.
Idris> String /= Bool
Can't find implementation for Eq Type
Am I missing an import?
You can't as it would break parametricity, which we have in Idris. We can't pattern match on types. But this would be necessary to write the Eq implementation, for example:
{- Doesn't work!
eqNat : Type -> Bool
eqNat Nat = True
eqNat _ = False -}
Also, if one could pattern match on types, they would be needed in the run-time. Right now types get erased when compiling.
Just to add some simple examples to the above: types can't be pattern matched on, but there's a two parameter type constructor for propositional equality, described in the documentation section on Theorem Proving. Notice that the only constructor, Refl, makes only values of type (=) x x, where both type parameters are the same. (this is ≡ in Agda)
So this will typecheck:
twoPlusTwoEqFour : 2 + 2 = 4
twoPlusTwoEqFour = Refl
so will this:
stringEqString : String = String
stringEqString = Refl
but not this:
stringEqInt : String = Int
stringEqInt = Refl
-- type error: Type mismatch between String and Int
and this needs extra work to prove, because addition is defined by recursion on the left argument, and n + 0 can't be reduced further:
proof : n = n + 0