The following code gives an error:
Inductive mylist {A : Set} : Set :=
| mylist_Nil
| mylist_Cons : A -> mylist A -> mylist A.
The error is "mylist A" of type "Set" cannot be applied to the term "A" : "Set".
If I change "{A:Set}" to (A:Set) then it works fine.
What does the curly braces mean? Thanks!
Usually, arguments are declared using parentheses. Curly braces are used for implicit arguments. Implicit arguments are not passed to functions and type declarations like usual ones; instead, the Coq type-checker tries to figure out what they should be from the context.
You can force a constant to take all arguments explicitly with an # sign, like this: #mylist A.
For generic types like mylist, there isn't enough context for Coq to infer what the A parameter should be, so it is usually better to declare those parameters explicitly, with parentheses.
The Coq user manual has more information on implicit arguments.
Related
I've defined the following type which has the exact same structure as option.
Inductive optionX A := NoneX | SomeX (a : A).
While Check Some 1 correctly infers the type parameter A, Check SomeX 1 produces the message
The term "1" has type "nat" while it is expected to have type "Type".
Am I missing something? Note that it works fine if I explicitly provide the type parameter: Check SomeX(nat) 1.
Coq has an implicit arguments mechanism for this kind of situation:
Inductive optionX A := NoneX | SomeX (a : A).
Arguments NoneX {A}.
Arguments SomeX {A} a. (* Curly braces means "please try to infer this" *)
Check SomeX 1.
(* You can turn off argument inference with # *)
Check #NoneX nat. (* optionX nat *)
Note that the expression that you had earlier, SomeX(nat) 1, is parsed the same way as SomeX nat 1, which is the constant SomeX applied to the arguments nat and 1. The mechanism for supplying type arguments is the same as how you supply other kinds of arguments.
The reference manual has more information on implicit arguments.
I'm reading a bit about Scala currying here and I don't understand this example very much:
def foldLeft[B](z: B)(op: (B, A) => B): B
What is the [B] in square brackets? Why is it in brackets? The B after the colon is the return type right? What is the type?
It looks like this method has 2 parameter lists: one with a parameter named z and one with a parameter named op which is a function.
op looks like it takes a function (B, A) => B). What does the right side mean? It returns B?
And this is apparently how it is used:
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val res = numbers.foldLeft(0)((m, n) => m + n)
print(res) // 55
What is going on? Why wasn't the [B] needed when called?
In Scala documentation that A type (sometimes A1) is often the placeholder for a collection's element type. So if you have...
List('c','q','y').foldLeft( //....etc.
...then A becomes the reference for Char because the list is a List[Char].
The B is a placeholder for a 2nd type that foldLeft will have to deal with. Specifically it is the type of the 1st parameter as well as the type of the foldLeft result. Most of the time you actually don't need to specify it when foldLeft is invoked because the compiler will infer it. So, yeah, it could have been...
numbers.foldLeft[Int](0)((m, n) => m + n)
...but why bother? The compiler knows it's an Int and so does anyone reading it (anyone who knows Scala).
(B, A) => B is a function that takes 2 parameters, one of type B and one of type A, and produces a result of type B.
What is the [B] in square brackets?
A type parameter (that's also known as "generics" if you've seen something like Java before)
Why is it in brackets?
Because type parameters are written in brackets, that's just Scala syntax. Java, C#, Rust, C++ use angle brackets < > for similar purposes, but since arrays in Scala are accessed as arr(idx), and (unlike Haskell or Python) Scala does not use [ ... ] for list comprehensions, the square brackets could be used for type parameters, and there was no need for angular brackets (those are more difficult to parse anyway, especially in a language which allows almost arbitrary names for infix and postfix operators).
The B after the colon is the return type right?
Right.
What is the type?
Ditto. The return type is B.
It looks like this method has 2 parameter lists: one with a parameter named z and one with a parameter named op which is a function.
This method has a type parameter B and two argument lists for value arguments, correct. This is done to simplify the type inference: the type B can be inferred from the first argument z, so it does not have to be repeated when writing down the lambda-expression for op. This wouldn't work if z and op were in the same argument list.
op looks like it takes a function (B, A) => B.
The type of the argument op is (B, A) => B, that is, Function2[B, A, B], a function that takes a B and an A and returns a B.
What does the right side mean? It returns B?
Yes.
What is going on?
m acts as accumulator, n is the current element of the list. The fold starts with integer value 0, and then accumulates from left to right, adding up all numbers. Instead of (m, n) => m + n, you could have written _ + _.
Why wasn't the [B] needed when called?
It was inferred from the type of z. There are many other cases where the generic type cannot be inferred automatically, then you would have to specify the return type explicitly by passing it as an argument in the square brackets.
This is what is called polymorphism. The function can work on multiple types and you sometimes want to give a parameter of what type will be worked with. Basically the B is a type parameter and can either be given explicitly as a type, which would be Int and then it should be given in square brackets or implicitly in parentheses like you did with the 0. Read about polymorphism here Scala polymorphism
Can someone please walk through this piece of scala syntax for me? I am new to the language, coming from Java.
val map = Map(seq map { a => a.key -> a }: _*)
In particular I understand a => a.key -> a is an anonymous function that returns a pair(?) (a.key, a) for each a, but what does : _*, { } do and why is there a space between seq and map? Are they arguments to the Map constructor?
: _* tells the compiler to pass each element of arr as its own argument to the function, rather than all of it as a single argument. Or to say in other words it is a special instance of type ascription which tells the compiler to treat a single argument of a sequence type as a variable argument sequence, i.e. varargs.
The _* type annotation is covered in "4.6.2 Repeated Parameters" of the SLS.
The last value parameter of a parameter section may be suffixed by “*”, e.g. (..., x:T *). The type of such a repeated parameter inside the method is then the sequence type scala.Seq[T]. Methods with repeated parameters T * take a variable number of arguments of type T . That is, if a method m with type (p1 : T1, . . . , pn : Tn,ps : S*)U is applied to arguments (e1, . . . , ek) where k >= n, then m is taken in that application to have type (p1 : T1, . . . , pn : Tn,ps : S, . . . , ps0S)U, with k ¡ n occurrences of type S where any parameter names beyond ps are fresh. The only exception to this rule is if the last argument is marked to be a sequence argument via a _* type annotation. If m above is applied to arguments (e1, . . . , en,e0 : _*), then the type of m in that application is taken to be (p1 : T1, . . . , pn : Tn,ps :scala.Seq[S])
{ } indicates a block of code, which is composed of multiple statements and declarations, and whose value is that of the last statement. If you need declarations, multiple statements, an import or anything like that, you need curly braces
Scala has a special punctuation-free syntax for invoking methods that take one argument. General rule is Scala methods that take a single parameter can be invoked without dots or parentheses.
In addition to Ramesh's answer.. your seq is most likely a Scala collection. Scala collections have numerous methods like map, filter, fold, reduce etc etc. So map is a method call on seq which is called without using the dot operator. This is allowed in Scala iff the method takes a single parameter.
The _* is somewhat weirder. Immutable Map requires a vararg as parameter. But the map method on seq will return a Map. The _* is in position of "type". By type, I simply mean, if I write i: Int, so Int is the type. So when an object's type is marked as _*, automatic type conversion takes place by the compiler which uses a factory to convert the object into a vararg. Like in Java, varargs can only appear as last parameter in a parameter list.
When needing to do some type conversion in Swift, I noticed the language has two separate syntax forms for this. I was able to write this:
arr as [Any]
but also this:
[Any](arr)
What is the difference between these? It seems that in general, for any value v and type T, I can write all of these:
Expression Has type Behavior
========== ======== ==============================================
v as T T Compile error if v cannot have type T
v as? T T? Evaluates to nil if v does not have type T
v as! T T Runtime error if v does not have type T
T(v) T ???
Questions: What the name is for syntax form T(v)? What are its semantics?
The syntax T(v) is not a form of type-casting – it's initialisation. Saying T(v) will create a new instance of T by calling T's init(_:) that takes a v argument.
In the case of [Any](arr), this is just syntactic sugar for Array<Any>.init(arr) – which is Array's init(_:) initialiser that accepts a Sequence of elements of the same static type as the Array's Element type (in this case, Any). It will simply create a new array containing the elements of this sequence.
When programming in Scala, I do more and more functional stuff. However, when using infix notation it is hard to tell when you need parenthesis and when you don't.
For example the following piece of code:
def caesar(k:Int)(c:Char) = c match {
case c if c isLower => ('a'+((c-'a'+k)%26)).toChar
case c if c isUpper => ('A'+((c-'A'+k)%26)).toChar
case _ => c
}
def encrypt(file:String,k:Int) = (fromFile(file) mkString) map caesar(k)_
The (fromFile(file) mkString) needs parenthesis in order to compile. When removed I get the following error:
Caesar.scala:24: error: not found: value map
def encrypt(file:String,k:Int) = fromFile(file) mkString map caesar(k)_
^
one error found
mkString obviously returns a string on which (by implicit conversion AFAIK)I can use the map function.
Why does this particular case needs parentheses? Is there a general guideline on when and why you need it?
This is what I put together for myself after reading the spec:
Any method which takes a single parameter can be used as an infix operator: a.m(b) can be written a m b.
Any method which does not require a parameter can be used as a postfix operator: a.m can be written a m.
For instance a.##(b) can be written a ## b and a.! can be written a!
Postfix operators have lower precedence than infix operators, so foo bar baz means foo.bar(baz) while foo bar baz bam means (foo.bar(baz)).bam and foo bar baz bam bim means (foo.bar(baz)).bam(bim).
Also given a parameterless method m of object a, a.m.m is valid but a m m is not as it would parse as exp1 op exp2.
Because there is a version of mkString that takes a single parameter it will be seen as an infix opertor in fromFile(file) mkString map caesar(k)_. There is also a version of mkString that takes no parameter which can be used a as postfix operator:
scala> List(1,2) mkString
res1: String = 12
scala> List(1,2) mkString "a"
res2: String = 1a2
Sometime by adding dot in the right location, you can get the precedence you need, e.g. fromFile(file).mkString map { }
And all that precedence thing happens before typing and other phases, so even though list mkString map function makes no sense as list.mkString(map).function, this is how it will be parsed.
The Scala reference mentions (6.12.3: Prefix, Infix, and Postfix Operations)
In a sequence of consecutive type infix operations t0 op1 t1 op2 . . .opn tn, all operators op1, . . . , opn must have the same associativity.
If they are all left-associative, the sequence is interpreted as (. . . (t0 op1 t1) op2 . . .) opn tn.
In your case, 'map' isn't a term for the operator 'mkstring', so you need grouping (with the parenthesis around 'fromFile(file) mkString')
Actually, Matt R comments:
It's not really an associativity issue, more that "Postfix operators always have lower precedence than infix operators. E.g. e1 op1 e2 op2 is always equivalent to (e1 op1 e2) op2". (Also from 6.12.3)
huynhjl's answer (upvoted) gives more details, and Mark Bush's answer (also upvoted) point to "A Tour of Scala: Operators" to illustrate that "Any method which takes a single parameter can be used as an infix operator".
Here's a simple rule: never used postfix operators. If you do, put the whole expression ending with the postfix operator inside parenthesis.
In fact, starting with Scala 2.10.0, doing that will generate a warning by default.
For good measure, you might want to move the postfix operator out, and use dot notation for it. For example:
(fromFile(file)).mkString map caesar(k)_
Or, even more simply,
fromFile(file).mkString map caesar(k)_
On the other hand, pay attention to the methods where you can supply an empty parenthesis to turn them into infix:
fromFile(file) mkString () map caesar(k)_
The spec doesn't make it clear, but my experience and experimentation has shown that the Scala compiler will always try to treat method calls using infix notation as infix operators. Even though your use of mkString is postfix, the compiler tries to interpret it as infix and so is trying to interpret "map" as its argument. All uses of postfix operators must either be immediately followed by an expression terminator or be used with "dot" notation for the compiler to see it as such.
You can get a hint of this (although it's not spelled out) in A Tour of Scala: Operators.