No '...' candidates produce 'Range<String.Index>' - ios

While converting an old iOS app to Sift 3.0 I hit the following issue:
The code is:
cutRange = numberString.index(numberString.startIndex, offsetBy:2)...numberString.index(numberString.startIndex, offsetBy:5)
The error message I get is:
No '...' candidates produce the expected contextual result type 'Range<String.Index>' (aka 'Range<String.CharacterView.Index>')
I have seen a few post related to the subject, but was not very satisfied.
So what is the simplest way to solve this problem?

In Swift 3, two range operators generate different results:
closed range operator ... -> ClosedRange (by default)
(half open) range operator ..< -> Range (by default)
So, assuming your cutRange is declared as Range<String.Index>, you need to use half open range operator ..<:
cutRange = numberString.index(numberString.startIndex, offsetBy:2)..<numberString.index(numberString.startIndex, offsetBy:6)
(Please do not miss the last offset is changed to 6.)

Related

Dart List negative indexing does not work

Dart's List Structure doesn't seem to support negative indexing. What is the reasoning behind this? Every other language I have ever used supports this. Why did dart decide to exclude such a basic construct?
The following code -
void main() {
List<String> x = ["foo", "bar"];
print(x[-1]);
}
Produces -
Uncaught exception:
RangeError (index): Index out of range: index must not be negative: -1
Dart does not support negative indexes.
To access elements relative to the end, you can calculate the index using
print(x[x.length - 1])
You can create a feature request in https://github.com/dart-lang/sdk to get feedback from the language designers.
To print the last element, you can simply use:
print(x.last);

Is there a simple method for left open just like right open for range in switch?

There is simple if right open [0,1) as the following,
let val: Float = 0
switch val {
case 0..<1:
...
}
But for (0, 1], is there a piece of similar simple code?
There is no standard operator to create a left-open range, and there is no standard type to represent a left-open range.
You could define an operator that creates a closed range after adding 1 to the left bound, but you cannot spell it <... From The Swift Programming Language (Swift 4):
If an operator doesn’t begin with a dot, it can’t contain a dot elsewhere. For example, +.+ is treated as the + operator followed by the .+ operator.

Result values in '? :' expression have mismatching types '()' and 'Bool' [duplicate]

This question already has answers here:
Swift ternary operator compilation error
(2 answers)
Closed 6 years ago.
I have an array of Doubles, and a button which when pressed empties the array. I want the button to be enabled only when the count of the array is greater than zero. The code is the following:
var numbers: [Double] = [] //At some point I add some numbers here
numbers.count > 0 ? deleteAllNumbersButton.isEnabled = true : deleteAllNumbersButton.isEnabled = false
The compiler complains:
Result values in '? :' expression have mismatching types '()' and
'Bool'
When put in an if statement it works just fine though. I can't understand the issue here. Has anyone seen this before? I use XCode 8.2.1 and Swift 3.
Note, I don't know Swift, but this doesn't appear to be a Swift specific problem. I can't explain the exact error, but I can show you how to write it properly.
Conditional expressions are used almost exclusively when you need to assign something to a variable or return a value, and have exactly 2 options to choose from.
This is what you're trying to do, but you've written it in a convoluted way that's likely confusing the compiler.
In the expression:
numbers.count > 0 ? deleteAllNumbersButton.isEnabled = true
: deleteAllNumbersButton.isEnabled = false
Because the "then" and "else" expressions both contain assignments, they evaluate (I'm assuming) to a Unit (())/"void". I'm guessing this is why it's yelling at you. It never makes sense to use a ternary to return a Unit (Actually, as noted in the comments, operator precedence is the real reason for the error).
What you likely meant was:
deleteAllNumbersButton.isEnabled = numbers.count > 0 ? true : false
Notice how instead of assigning in the conditional expression, the result of the expression is instead assigned. In cases that can't be simplified further (see below), this is how conditional expressions should be used.
This new form should raise red flags though. Why have the conditional expression evaluate to true/false? That's almost always a code smell. It's redundant given the condition already evaluates to a Boolean value.
Just reduce it down to:
deleteAllNumbersButton.isEnabled = numbers.count > 0

Erlang Dialyzer: only accept certain integers?

Say I have a function,foo/1, whose spec is -spec foo(atom()) -> #r{}., where #r{} is a record defined as -record(r, {a :: 1..789})., however, I have foo(a) -> 800. in my code, when I run dialyzer against it, it didn't warn me about this, (800 is not a "valid" return value for function foo/1), can I make dialyzer warn me about this?
Edit
Learn You Some Erlang says:
Dialyzer reserves the right to expand this range into a bigger one.
But I couldn't find how to disable this.
As of Erlang 18, the handling of integer ranges is done by erl_types:t_from_range/2. As you can see, there are a lot of generalizations happening to get a "safe" overapproximation of a range.
If you tried to ?USE_UNSAFE_RANGES (see the code) it is likely that your particular error would be caught, but at a terrible cost: native compilation and dialyzing of recursive integer functions would not ever finish!
The reason is that the type analysis for recursive functions uses a simple fixpoint approach, where the initial types accept the base cases and are repeatedly expanded using the recursive cases to include more values. At some point overapproximations must happen if the process is to terminate. Here is a concrete example:
fact(1) -> 1;
fact(N) -> N * fact(N - 1).
Initially fact/1 is assumed to have type fun(none()) -> none(). Using that to analyse the code, the second clause is 'failing' and only the first one is ok. Therefore after the first iteration the new type is fun(1) -> 1. Using the new type the second clause can succeed, expanding the type to fun(1|2) -> 1|2. Then fun(1|2|3) -> 1|2|6 this continues until the ?SET_LIMIT is reached in which case t_from_range stops using the individual values and type becomes fun(1..255) -> pos_integer(). The next iteration expands 1..255 to pos_integer() and then fun(pos_integer()) -> pos_integer() is a fixpoint!
Incorrect answer follows (explains the first comment below):
You should get a warning for this code if you use the -Woverspecs option. This option is not enabled by default, since Dialyzer operates under the assumption that it is 'ok' to over-approximate the return values of a function. In your particular case, however, you actually want any extra values to produce warnings.

Deedle IndexRows type annotations

I was trying to implement a Deedle solution for the little challenge from #migueldeicaza to achieve in F# what was done in http://t.co/4YFXk8PQaU with python and R. The csv source data is available from the link.
The start is simple but now, while trying to order based upon a column series of float values I'm struggling to understand the syntax for the IndexRows type annotation.
#I "../packages/FSharp.Charting.0.90.5"
#I "../packages/Deedle.0.9.12"
#load "FSharp.Charting.fsx"
#load "Deedle.fsx"
open System
open Deedle
open FSharp.Charting
let bodyCountData = Frame.ReadCsv(__SOURCE_DIRECTORY__ + "/film_death_counts.csv")
bodyCountData?DeathsPerMinute <- bodyCountData?Body_Count / bodyCountData?Length_Minutes
// select top 3 rows based upon default ordinal indexer
bodyCountData.Rows.[0..3]
// create a new frame indexed and ordered by descending number of screen deaths per minute
let bodyCountDataOrdered =
bodyCountData
|> Frame.indexRows <float>"DeathsPerMinute" // uh oh error here - I'm confused
And because I can't figure that syntax out... various messages like:
Error 1 The type '('a -> Frame<'c,Frame<int,string>>)' does not support the 'comparison' constraint. For example, it does not support the 'System.IComparable' interface. See also c:\wd\RPythonFSharpDFChallenge\RPythonFSharpDFChallenge\EvilMovieQuery.fsx(18,4)-(19,22). c:\wd\RPythonFSharpDFChallenge\RPythonFSharpDFChallenge\EvilMovieQuery.fsx 19 8 RPythonFSharpDFChallenge
Error 2 Type mismatch. Expecting a
'a -> Frame<'c,Frame<int,string>>
but given a
'a -> float
The type 'Frame<'a,Frame<int,string>>' does not match the type 'float' c:\wd\RPythonFSharpDFChallenge\RPythonFSharpDFChallenge\EvilMovieQuery.fsx 19 25 RPythonFSharpDFChallenge
Error 3 This expression was expected to have type
bool
but here has type
string c:\wd\RPythonFSharpDFChallenge\RPythonFSharpDFChallenge\EvilMovieQuery.fsx 19 31 RPythonFSharpDFChallenge
Edit: Just thinking about this... indexing on a measured float is a silly thing to do anyway - duplicates and missing values in real world data. So, I wonder what a more sensible approach to this would be. I still need to find the 25 max values... Maybe I can work this out for myself...
With Deedle 1.0, you can sort on an arbitrary column.
See: http://bluemountaincapital.github.io/Deedle/reference/deedle-framemodule.html#section7

Resources