error in elm-lang `(==) is expecting the right side to be a:` - typeerror

New to elm here, and at first it's driving me absolutely crazy not knowing the ins and outs of this picky language (even after reading a sh**load about it because it's just so different and finicky... I guess that's the nature of a functional lang) so when you try doing a simple thing it's like pulling hair at first.
I am getting the following error:
The right side of (==) is causing a type mismatch.
29| get 0 arrayOfValues == 'X'
^^^
(==) is expecting the right side to be a:
Maybe Char
But the right side is:
Char
Hint: With operators like (==) I always check the left side first. If it seems
fine, I assume it is correct and check the right side. So the problem may be in
how the left and right arguments interact.
Test:
it "blah blah blah" <|
let
someArray =
[ 'P', ' ' ]
in
expect (MyModule.doSomething someArray 'P') to equal 1
MyModule
doSomething : List Char -> Char -> Int
doSomething arrayOfValues symbol =
let
grid =
fromList arrayOfValues
found =
get 0 arrayOfValues == symbol
in
if found then
1
else
0
Now I'm assuming but not sure, that it's getting Nothing or something when trying to pull the first value out of my array but not sure. Maybe Char I assume is returning Nothing? donno, probably have other issues going on with it too.
I'd like to get the code above working, then refactor..I'm sure there's probably a more elegant way to code what I've coded above but first thing's first, fixing this error and understanding it better with the existing code. The error message while nice isn't that obvious to me as to how and what to handle. I have assumptions but not fully sure how to handle the behavior here of whatever is causing the issue.

Unique feature of the elm is certainty. Any variable (which is not of type maybe) will have a value of the defined type for sure.
But when it comes to array or list, it becomes uncertain if the array has an element on index "i". There may be an element and there may not be.
Hence elm has concept of Maybe,
so conceptually
Maybe String = [ Just "string_value" | Nothing ]
the alias for the Array.get is
get : Int -> Array a -> Maybe a
it takes
Int - index and
Array a - array of data type of array element
as parameters and returns
Maybe a - again a is the data type of array element
consider an example
array =
fromList ["one", "two"]
val1 =
get 0 array -- will return 'Just "one"'
val2 =
get 3 array -- will return 'Nothing', since the element does not exists
this way you will always have to handle both the situations, when you have a value and when you don't
case val1 of
Nothing ->
-- Raise some error message
Just val ->
-- `val` is the actual element/value found
and if you always need a default value, you can use
Maybe.withDefault "default_string" val1
this will always return a string value and will return "default_string" when the value is nothing otherwise the actual found value

Related

Even when constant is define as 1 to maxint , 0 is still accepted in Pascal

I'm confused because when I define a type from 1 to maxint in Pascal and I make the choice "0" which should return back to the repeat loop. Here is my code:
program Tanken;
type
tZahl = 1..maxint;
var
tag1 : tZahl;
wahl : tZahl;
liter,
p : real;
BEGIN
repeat
write ('Bitte Tag eingeben 1=Mon 2=Die 3=Mit 4=Don 5=Fre 6=Sam 7=Son: ');
readln (tag1);
writeln(tag1);
until tag1 <= 7;
....
end
This is how my constant, type and variable looks. Si I define tag1 as tZahl which should be from 1 to maxint but how ever when I run this at the first repeat loop when I type "0" it is accepted. I found this a bit confusing any ideas?
To force type range checking at runtime you need to explicitly tell the compiler to with most used compilers by adding {$R+} to the top of the program.
However this will only throw a runtime error, which is not the input validation that you want. You will really need to program input validation yourself. E.g. by reading a string, and then converting it to a number using the VAL() procedure and checking the code argument for errors.

What are the advantages of returning -1 instead of null in indexOf(...)?

When calling List.indexOf(...), what are the advantages of returning -1 rather than null if the value isn't present?
For example:
val list = listOf("a", "b", "c")
val index = list.indexOf("d")
print(index) // Prints -1
Wouldn't it be a cleaner result if index was null instead? If it had an optional return type, then it would be compatible with the elvis operator :? as well as doing things such as index?.let { ... }.
What are the advantages of returning -1 instead of null when there are no matches?
Just speculations but i could think of two reasons:
The first reason is to be compatible with Java and its List.indexOf
As the documentation states:
Returns:
the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element
The second reason is to have the same datatype as kotlins binarySearch.
Return the index of the element, if it is contained in the list within the specified range; otherwise, the inverted insertion point (-insertion point - 1). The insertion point is defined as the index at which the element should be inserted, so that the list (or the specified subrange of list) still remains sorted.
Where the negative values actually hold additional information where to insert the element if absent. But since the normal indexOf method works on unsorted collections you can not infer the insertion position.
To add to the definitive answer of #Burdui, another reason of such behavior is that -1 return value can be expressed with the same primitive Int type as the other possible results of indexOf function.
If indexOf returned null, it would require making its return type nullable, Int?, and that would cause a primitive return value being boxed into an object. indexOf is often used in a tight loop, for example, when searching for all occurrences of a substring in a string, and having boxing on that hot path could make the cost of using indexOf prohibitive.
On the other hand, there definitely can be situations where performance does not so matter, and returning null from indexOf would make code more expressive. There's a request KT-8133 to introduce indexOfOrNull extension for such situations.
Meanwhile a workaround with calling .takeIf { it >= 0 } on the result of indexOf allows to achieve the same.

Getting a Maybe instead of an Array's value

New to elm here, and at first it's driving me absolutely crazy not knowing the ins and outs of this picky language (even after reading a sh**load about it because it's just so different and finicky...I guess that's the nature of a functional lang) so when you try doing a simple thing it's like pulling hair at first.
I am getting the following error:
The right side of (==) is causing a type mismatch.
29| get 0 arrayOfValues == 'X'
^^^
(==) is expecting the right side to be a:
Maybe Char
But the right side is:
Char
Hint: With operators like (==) I always check the left side first. If it seems
fine, I assume it is correct and check the right side. So the problem may be in
how the left and right arguments interact.
Test:
it "blah blah blah" <|
let
someArray =
[ 'P', ' ' ]
in
expect (MyModule.doSomething someArray 'P') to equal 1
MyModule
doSomething : List Char -> Char -> Int
doSomething arrayOfValues symbol =
let
grid =
fromList arrayOfValues
found =
get 0 arrayOfValues == symbol
in
if found then
1
else
0
Now I'm assuming but not sure, that it's getting Nothing or something when trying to pull the first value out of my array but not sure. Maybe Char I assume is returning Nothing? donno, probably have other issues going on with it too.
I'd like to get the code above working, then refactor..I'm sure there's probably a more elegant way to code what I've coded above but first thing's first, fixing this error and understanding it better with the existing code. The error message while nice isn't that obvious to me as to how and what to handle. I have assumptions but not fully sure how to handle the behavior here of whatever is causing the issue.
Array.get returns a value wrapped in a Maybe because there might not be a value present at the specified index in the array. If you want to check whether the value at index 0 present and equal to 'X', you can compare to Just 'X':
get 0 arrayOfValues == Just 'X'
Like the error message says, the compiler found that the left side of == is a Maybe Char and the right is Char. You need to convert one to another to use ==. In this case, you probably want to change the right side as I suggested above.

When does = perform comparison instead of assignment?

In VB.NET, there's no == operator for comparison, so the = operator serves that purpose as well as assignment. I have a function, and I want it to return the boolean result of a comparison, without storing that result in a variable:
Private Function foo() As Boolean
Dim bar As Integer = 1
Return bar = 2
End Function
Returns: False
OK, but what's the value of bar?
Private Function foo() As KeyValuePair(Of Boolean, Integer)
Dim bar As Integer = 1
Return New KeyValuePair(Of Boolean, Integer)(bar = 2, bar)
End Function
Returns: False, 1
It looks like = will perform a comparison when the statement context demands it, but is this guaranteed? That is, can I be sure that bar will never be set to 2 in this situation?
Also, I know that VB.NET doesn't allow chained inline assignments, which may be for the best. Does this odd = behavior cause any other quirks I should be aware of?
You cannot do in-line assignments in VB, Assignment is an explicit statement:
[Let] <<target-reference>> = <<value-expression>>
The Let is optional and implicit, and hardly ever used anymore. The general rule that you can use to distinguish the [Let] command from equality testing is that for Let, no other keyword may come before the target-reference in the statement. AFAIK, in all cases of = as equality testing, there is one or more other keywords that precede it in the statement.
In your first example, the keyword Return precedes your =, so it's an equality test, and not an assignment.
In your first example you can do either:
Return 2
or
bar = 2
Return bar
As for your question "OK, but what's the value of bar?", bar still equals one.
= in VB cause no quirks. It works exactly as documented, and it always has (including its predecessor, BASIC back to 1968).
If you are starting to code in VB (coming from a language like C#), you should start getting used to the peculiar VB way of doing things; which is based on the idea: as simple and intuitive for the programmer as possible. "If assignation and comparison happen always in different contexts, why not using the same operator and let the context define its exact meaning?" -> VB-way of seeing things. "No, different realities have to be accounted for by different operators. End of the discussion" -> C#-way. :)
Is this reliable? Can you blindly trust on these not-always-clear-for-a-programmer bits? Sure, VB.NET peculiarities are highly-reliable and trustworthy. You can always use = (or Is on some contexts, but VS would tell you) and be completely sure that the code will do what is expected. But the question is: are you sure that you write exactly what you want?
This last question is what, perhaps, is more criticable of VB and what might give some problems to programmers from other languages: the higher the flexibility, the more likely is that you make an error; mainly if you are used to a different format.
Regarding the chained inline assignments, I honestly don't see its true utility (and never use them in C#). Regarding other differences with respect to C#, there are plenty of them; in some cases, I think that the C# approach is better; other times, the VB.NET one. On readability/length of code, I can refer to the With Statement I have always found somehow useful which is not present in C#.
One way to have 100% sure that the expression will be evaluated as an boolean expression is to use ()
e.g
Dim a = 2
Return (a = 1)
Since you cannot set a value to a variable wihtin the parenthesis.
What i want to say is: on an return statament for example you cant assing a value to a variable so, even if you use
a = 1
The compilator knows that this expression only can be an boolean expression.
The same to the if statament and so on..
Heh back in QB45 days we used to exploit the fact that "True" was the numeric value -1. So you would see code like x = 1 - x * (x < 6) (translation: increment x, but reset to 1 when it gets to 6)

Range over an arbitrary type

Is there a way to make an arbitrary type range-able in Go? For example, Python offers __iter__(), which is really useful. I tried searching for the answer but I got no results.
You've searched successfully, there's no support for ranging over arbitrary types in Go.
From the specs:
RangeClause = ( ExpressionList "=" | IdentifierList ":=" ) "range" Expression .
The expression on the right in the "range" clause is called the range expression, which may be an array, pointer to an array, slice, string, map, or channel permitting receive operations.
You can use channels to simulate it. Something along the lines of
func (t *SomeType) Range() chan *Item {
// setup a channel and a go routine that sends the items from t
}
for item := range t.Range()
...