Below the grammar i make.
S' -> sqf
sqf -> declarations
declarations -> declaration
declarations -> declaration declarations
declaration -> relation
declaration -> norelation
relation -> head body
norelation -> relatts
norelation -> reldata
norelation -> relatts reldata
head -> relname attributes
body -> reldata
body -> empty
relname -> RELKW IDENTIFIER
attributes -> relatts
attributes -> empty
relatts -> attname
relatts -> attname relatts
reldata -> DATAKW tuples
reldata -> DATAKW
tuples -> tuple
tuples -> tuple tuples
attname -> ATTKW IDENTIFIER
tuple -> VALUE
empty ->
The problem is that the grammar is ambiguous because for some rules there are shift/reduce conflicts. Particularly
at the rules below for DATAKW we have shift/reduce conflict
relation -> head body
body -> reldata
body -> empty
reldata -> DATAKW tuples
reldata -> DATAKW
*empty -> *
at the rules below for DATAKW we have shift/reduce conflict
norelation -> relatts
norelation -> relatts reldata
reldata -> DATAKW tuples
reldata -> DATAKW
at the rules below for ATTKW we have shift/reduce conflict
head -> relname attributes
attributes -> relatts
attributes -> empty
relatts -> attname
relatts -> attname relatts
*empty -> *
attname -> ATTKW IDENTIFIER
at the rules below for ATTKW we have shift/reduce conflict
relatts -> attname
relatts -> attname relatts
relatts -> attname
relatts -> attname relatts
attname -> ATTKW IDENTIFIER
Can anyone help me to solve that conflicts, please.
A problem is that the grammar cannot determine where one declaration ends and the next one begins.
A simple instance of this general problem: norelation can be just a relatts which can be a list of attnames. So if you have two consecutive norelation, that could be two sequences of attnames. How can you distinguish two consecutive sequences from one longer sequence? Or three shorter ones? Etc.
There are many other instances of the same issue.
Unless you've transcribed the language incorrectly, this is a problem of language design, and semicolons are a common solution.
Related
I am playing around with the custom operator >>> for function composition that is suggested here.
I have defined the following:
infix operator >>> { associativity left }
func >>> <A, B, C>(f: B -> C, g: A -> B) -> (A -> C) {
return { x in f(g(x)) }
}
func toChars(s: String) -> [Character] {
return s.characters.reduce([]) { (acc, c) in acc + [c] }
}
func myReverse(xs: [Character]) -> String {
if let (head, tail) = xs.decompose {
return String(myReverse(tail)) + String(head)
}
return ""
}
Now, when I want to put together those two functions like this:
func reverseString(s: String) -> String {
return myReverse >>> toChars
}
I am getting the compiler error:
Cannot convert value of type ([Character]) -> String to expected
argument type _ -> _.
According to my understanding this should work. >>> is defined to take two functions f : B -> C and g : A -> B. Looking at the structure of my usage, the following becomes clear:
g in this case is toChar : String -> [Character], so A is String and B is [Character]
f in this case is myReverse : [Character] -> String, so B is [Character] and C is String
This matches the type definitions form above, however I am still getting a compiler error. Does anyone know what I am doing wrong? Is there a syntax issue with the code?
Note, I am using an Array extension where the function decompose is defined like so:
var decompose : (head: Element, tail: [Element])? {
if count > 0 {
return (self[0], Array(self[1..<count]))
}
return nil
}
myReverse >>> toChars returns a closure of type String -> String,
you still have to call the closure with a string argument:
func reverseString(s: String) -> String {
return (myReverse >>> toChars)(s)
}
But what you probably want is:
let reverseString = myReverse >>> toChars
In both cases, reverseString has the type String -> String,
so you can call it as
print(reverseString("foo"))
// oof
I have the following code. I explicitly defined the return type as boolean
let inputChecker (romanNumber:list<char>) :bool = function
| [] -> false
| head::tail when head<= tail.Head && tail.Head<=tail.Tail.Head -> false
| _ -> true
but i think it consider the :bool as a parameter. I also tried (:bool), but still doesn't work.
If you use function, you don't specify the argument in the signature:
let inputChecker: (char list -> bool) = function
| [] -> false
| head::tail when head<= tail.Head && tail.Head<=tail.Tail.Head -> false
| _ -> true
If you want to specify the argument explicitly, use match
let inputChecker (romanNumber: char list): bool =
match romanNumber with
| [] -> false
| head::tail when head<= tail.Head && tail.Head<=tail.Tail.Head -> false
| _ -> true
Type annotations are not necessary, you can skip them.
I have this function that is going to calculate the hypotenuse from 2 numbers
func hypotenusa<T>(nr1: T, nr2: T) -> T {
return sqrt( pow(nr1, 2) + pow(nr2, 2) )
}
// v Simpler situation v
func addition<T>(nr1: T, nr2: T) -> T {
return nr1 + nr2
}
I want to use generics so I don't have to make 3 copies of this which uses Int, Float, Double separately
But this isn't working, I think generics is really difficult to work with, please help me :)
Swift generics aren't like C++ templates.
In C++, you can just try to use a parameterized type however you want, and it's not an error until the compiler tries to instantiate the template with some type that doesn't support what your template tries to do.
In Swift, the generic construct can only use a parameterized type in ways known to be valid when the generic construct is first parsed. You specify these "ways known to be valid" by constraining the parameterized type with protocols.
You cannot call sqrt or pow with generic-typed arguments, because those functions are not themselves generic. They have each two definitions:
func pow(_: Double, _: Double) -> Double
func pow(lhs: Float, rhs: Float) -> Float
func sqrt(x: Double) -> Double
func sqrt(x: Float) -> Float
You could write type-specific versions of hypotenusa:
func hypotenusa(a: Float, b: Float) -> Float
func hypotenusa(a: Double, b: Double) -> Double
func hypotenusa(a: CGFloat, b: CGFloat) -> CGFloat
I'm not sure why you'd create an Int version at all, since very few right triangles have integer hypotenuses.
Anyway, you don't need to define the Float and Double versions at all, because the standard library already provides a hypot function defined on Float and Double:
func hypot(_: Double, _: Double) -> Double
func hypot(lhs: Float, rhs: Float) -> Float
You could create another override for CGFloat:
func hypot(l: CGFloat, r: CGFloat) -> CGFloat {
return hypot(Double(l), Double(r))
}
As for your addition function, it has the same problem as your hypotenusa function: the + operator is not defined entirely generically. It has some generic definitions (unlike sqrt and pow), but those only cover the integer types (see IntegerArithmeticType). There's not generic definition of + that covers the floating-point types. Swift defines all of these versions of + with explicit types:
func +(lhs: Float, rhs: Float) -> Float
func +<T>(lhs: Int, rhs: UnsafePointer<T>) -> UnsafePointer<T>
func +<T>(lhs: UnsafePointer<T>, rhs: Int) -> UnsafePointer<T>
func +(lhs: Int, rhs: Int) -> Int
func +(lhs: UInt, rhs: UInt) -> UInt
func +(lhs: Int64, rhs: Int64) -> Int64
func +(lhs: UInt64, rhs: UInt64) -> UInt64
func +<T>(lhs: Int, rhs: UnsafeMutablePointer<T>) -> UnsafeMutablePointer<T>
func +<T>(lhs: UnsafeMutablePointer<T>, rhs: Int) -> UnsafeMutablePointer<T>
func +(lhs: Int32, rhs: Int32) -> Int32
func +(lhs: UInt32, rhs: UInt32) -> UInt32
func +(lhs: Int16, rhs: Int16) -> Int16
func +(lhs: UInt16, rhs: UInt16) -> UInt16
func +(lhs: Int8, rhs: Int8) -> Int8
func +(lhs: UInt8, rhs: UInt8) -> UInt8
func +(lhs: Double, rhs: Double) -> Double
func +(lhs: String, rhs: String) -> String
func +(lhs: Float80, rhs: Float80) -> Float80
With Swift 5, according to your needs, you can pick one of the following ways in order to solve your problem.
#1. Using FloatingPoint protocol as a parameter generic constraint
The Apple Developer Documentation for FloatingPoint shows the following hypotenuse function implementation as an example of FloatingPoint usage:
func hypotenuse<T: FloatingPoint>(_ a: T, _ b: T) -> T {
return (a * a + b * b).squareRoot()
}
let (dx, dy) = (3.0, 4.0)
let result = hypotenuse(dx, dy)
print(result) // prints: 5.0
#2. Using AdditiveArithmetic protocol as a parameter generic constraint
AdditiveArithmetic has the following declaration:
A type with values that support addition and subtraction.
The Playground sample code below shows a possible usage of AdditiveArithmetic as a function parameter generic constraint:
func addition<T: AdditiveArithmetic>(a: T, b: T) -> T {
return a + b
}
let result = addition(a: 3, b: 4)
print(result) // prints: 7
#3. Using Numeric protocol as a parameter generic constraint
Numeric has the following declaration:
A type with values that support multiplication.
The Playground sample code below shows a possible usage of Numeric as a function parameter generic constraint:
func multiply<T: Numeric>(a: T, b: T, c: T) -> T {
return a * b * c
}
let result = multiply(a: 3, b: 4, c: 5)
print(result) // prints: 60
Note that Numeric protocol inherit from AdditiveArithmetic protocol.
The Apple Developer Documentation contains a dedicated page for all numeric protocols: Numeric Protocols.
I think this is what you need:
You need to explicitly create a new protocol and extend the types you want (Int, Float, Double) to conform to the protocol. Than in your generic declaration you do
func addition<T: protocolJustCreated>(nr1: T, nr2: T) -> T {}
Read the answer I linked for a more complete answer. No need to repeat here.
Sqrt() and pow() both specify their parameters as either double or float. In order to meet your goal of using this one function for Int, Float, and Double you will need to also make generics of sqrt() and pow() functions.
I am trying practice writing transducers in swift, but I cannot successfully translate this functional javascript code to swift.
http://phuu.net/2014/08/31/csp-and-transducers.html
function mapping(transform) {
return function (reduce) {
return function (result, input) {
return reduce(result, transform(input));
};
};
}
func mapping<T,U> ( transform:(T)-> T ) -> ( (U,T)-> ( (U,T)->U ) ) {
return { ( transducer:(U,T) ) -> ( (U,T)->U ) in
return { (initial:U,element:T) -> U in
var transformedElement = transform(element);
var mInitial = transducer(initial,transformedElement); // this line is the problem
return mInitial;
}
}
func addOne (a:Int) -> (Int) {
return a+1;
}
func concat (c:Array<Int>,element:Int) -> (Array<Int>) {
var collection = c;
collection.append(element);
return collection;
}
var example3 = [1,2,3].reduce([], concat( mapping ( addOne ) ) );
According to http://phuu.net/2014/08/31/csp-and-transducers.html
and http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming,
a reducing function has the signature
whatever, input -> whatever
In Swift, this is a function (or closure) of the type
(U, T) -> U
(using the usual short names T, U for generic types).
A transducer is a function that takes one reducing function as an argument
and returns another reducing function
(whatever, input -> whatever) -> (whatever, input -> whatever)
The corresponding Swift type is
((U,T) -> U) -> (U,T) -> U
mapping() takes a transformation as an argument an returns a transducer,
so it must be defined as
func mapping<T,U> (transform:(T) -> T) -> ((U,T)->U) -> (U,T) -> U
(Also the parameter in the first inner function of mapping is better called
"reducer" instead of "transducer", because it is the argument of the return value.)
In your example,
concat : ([Int], Int) -> [Int]
is a reducing function and mapping(addOne) is a transducer, therefore
mapping(addOne)(concat) : ([Int], Int) -> [Int]
is another reducing function, so that
var example3 = [1,2,3].reduce([], mapping(addOne)(concat))
gives the result [2,3,4].
Complete sample code:
func mapping<T,U> (transform:(T) -> T) -> ((U,T)->U) -> (U,T) -> U {
return { (reducer:((U,T) -> U)) -> (U,T) -> U in
return { (initial:U, element:T) -> U in
return reducer(initial,transform(element))
}
}
}
func addOne (a:Int) -> (Int) {
return a+1;
}
// Slightly simplified and generalized:
func concat<T> (c:[T], element:T) -> [T] {
return c + [element];
}
var example3 = [1,2,3].reduce([], mapping (addOne)(concat))
println(example3) // [2, 3, 4]
How do I write a match function that takes two strings and compares them with each other? Right now I just have this. The first one does not work. Is there a better way?
let matchFn ([<Literal>]matchString) (aString : string) = match aString with
matchString -> true
| _ -> false
let matchFn (matchString : string) (aString : string) = match aString with
_ when (matchString = aString) -> true
| _ -> false
In this specific case, you could of course just write aString = matchString, but I suppose you are asking about the general case. Literals are allowed only on the module level, and they must have a simple constant expression on their right side (source).
However, you can use an active pattern for cases like this. For example (from here):
let (|Equals|_|) expected actual =
if actual = expected then Some() else None
and then use it like this:
let matchFn (matchString : string) (aString : string) =
match aString with
| Equals matchString -> true
| _ -> false
You can use a guarded match:
let matchFn matchString (aString : string) = match aString with
x when x = matchString -> true
| _ -> false
or, perhaps more idiomatically:
let matchFn (matchString:string) = function
| x when x = matchString -> true
| _ -> false