Skip to content

Instantly share code, notes, and snippets.

@BestKora
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BestKora/f1c9d453b1f43a4a6fd3 to your computer and use it in GitHub Desktop.
Save BestKora/f1c9d453b1f43a4a6fd3 to your computer and use it in GitHub Desktop.
Код к серии статей "Управление ошибками в Swift: магия и реальность. http://www.bestkora.com/SwiftLearning/upravlenie-oshibkami-v-swift-magiya-i-realn/
// Playground - noun: a place where people can play
import Foundation
// ДЛЯ СТАТЬИ http://nomothetis.svbtle.com/error-handling-in-swift
// Управление ошибками в Swift: магия и реальность - Часть 2
// http://www.bestkora.com/SwiftLearning/upravlenie-oshibkami-v-swift-magiya-i-realn/
// ============= Обычная функция ===========
func divide0 (a: Float, by: Float ) -> Float {
return a/by
}
// ------Тестовый пример 1
let result0 = divide0(2.5, 3)
// ============ Возврат ошибки NSError ======
// Для упрощения работы с классом NSError создаем "удобный" инициализатор в расширении класса
extension NSError {
convenience init(localizedDescription: String) {
self.init(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: localizedDescription])
}
}
func divide1 (a:Float, by:Float, inout error:NSError) -> Float?{
switch by{
case 0:
error = NSError(localizedDescription: "Деление на нуль")
return nil
default:
return a/by
}
}
var err = NSError(localizedDescription: "OK");
// ------Тестовый пример 1
var result1 = divide1(2.5, 3, &err)
println("\(result1)")
println("\(err.localizedDescription)")
// ------Тестовый пример 2
result1 = divide1(2.5, 0, &err)
println("\(result1)")
println("\(err.localizedDescription)")
//======== Результат в виде перечисления Result<T>============
enum Result<T> :Printable {
case Success(Box<T>)
case Failure(NSError)
var description : String {
get {
switch self{
case .Success(let value):
return "\(value.unbox)"
case .Failure(let err):
return "\(err.localizedDescription)"
}
}
}
func map<P>(f: T -> P) -> Result<P> {
switch self {
case .Success(let value):
return .Success(Box(f(value.unbox)))
case .Failure(let err):
return .Failure(err)
}
}
func flatMap<P>(f:T -> Result<P>) -> Result<P> {
switch self {
case .Success(let value):
return f(value.unbox)
case .Failure (let err):
return .Failure(err)
}
}
}
final class Box<T> {
let unbox: T
init(_ value: T) { self.unbox = value }
}
func divide (a:Float, by:Float) -> Result<Float>{
switch by{
case 0: return .Failure(NSError(localizedDescription: "Деление на нуль"))
default:
return .Success(Box(a/by))
}
}
// ------Тестовый пример 1
var result = divide(2.5, 0.3 )
println(result.description)
// ------Тестовый пример 2
result = divide(2.5, 0 )
println(result.description)
//======== map ============
func magicNumber(quotient:Float) -> Float {
let lpf = sin(quotient)
return log(lpf)
}
func spelling(quotient:Float) -> String {
let lpf = quotient.description
return lpf
}
// ------Тестовый пример 1
result = divide(2.5, 0.3 )
var result2 = result.map(magicNumber).map(spelling)
println(result2.description)
// ------Тестовый пример 2
result = divide(2.5, 0 )
result2 = result.map(magicNumber).map(spelling)
println(result2.description)
// ------Тестовый пример 3
result = divide(2.5, 0.3 )
result2 = result.map(sin).map(log).map(spelling)
println(result2.description)
// ДЛЯ СТАТЬИ http://nomothetis.svbtle.com/error-handling-in-swift-part-ii
// Управление ошибками в Swift: магия и реальность - Часть 2
// http://www.bestkora.com/SwiftLearning/upravlenie-oshibkami-v-swift-vozmozhnosti-i/
//======== flat map ============
func log1 (a:Float) -> Result<Float>{
switch a {
case let x where x <= 0: return .Failure(NSError(localizedDescription: "Логарифм отрицательного числа"))
default:
return .Success(Box(a))
}
}
func magicNumber1(quotient:Float) -> Result<Float> {
let sinus = sin(quotient)
return log1(sinus)
}
// ------Тестовый пример 1
result = divide(2.5, 0.3 )
var result3 = result.map(sin).flatMap(log1).map(spelling)
println(result3.description)
// ------Тестовый пример 2
result = divide(2.5, 0.3 )
result3 = result.flatMap(magicNumber1).map(spelling)
println(result3.description)
// ------Тестовый пример 3 (деление на нуль)
result = divide(2.5, 0 )
result3 = result.flatMap(magicNumber1).map(spelling)
println(result3.description)
// ------Тестовый пример 4 (логифм отрицательного числа)
result = divide(2.5, -2.0 )
result3 = result.flatMap(magicNumber1).map(spelling)
println(result3.description)
// БОНУС ======== curried function ============
func divide3 (a:Float) (by:Float) -> Result<Float>{
return divide (a,by)
}
// ------Тестовый пример 1 -- просто curry
var result4 = divide3(2.5)(by: 3)
println(result4.description)
// ------Тестовый пример 2 -- curry и map, flatMap
var result5 = divide3(2.5)(by: 0.3).map(sin).flatMap(log1).map(spelling)
println(result5.description)
// ------Тестовый пример 3 -- 1/result4 интересный вариант
var result6 = divide3(2.5)(by: 0.3).map(sin).flatMap(log1).flatMap(divide3(1)).map(spelling)
println(result6.description)
//.map({$0/3})
println( divide(1.0, 0.887294232845306).description)
// ------Тестовый пример 4 -- 1/result4 /3 и closure {$0/3}
var result7 = divide3(2.5)(by: 0.3).map(sin).flatMap(log1).flatMap(divide3(1)).map({$0/3}).map(spelling)
println(result7.description)
//==== Для статьи http://nomothetis.svbtle.com/understanding-optional-chaining
// Понимание Optional Chaining
// http://www.bestkora.com/SwiftLearning/ponimanie-optional-chaining/
infix operator |- { associativity left precedence 150 }
func |-<T, U>(opt:T?, f: T -> U?) -> U? {
switch opt {
case .Some(let x):
return f(x)
case .None:
return .None
}
}
public class Demo {
public let subDemo:SubDemo?
init(subDemo sDemo:SubDemo? = nil) {
self.subDemo = sDemo
}
}
public class SubDemo {
public let count:Int = 1
public func two() ->Int {return 2}
}
// ----- Тестовый пример 1 оператор |-
let aDemo:Demo? = nil
let bDemo:Demo? = Demo()
let cDemo:Demo? = Demo(subDemo: SubDemo())
let aCount = aDemo |- { $0.subDemo } |- { $0.count } // {None}
let bCount = bDemo |- { $0.subDemo } |- { $0.count } // {None}
let cCount = cDemo |- { $0.subDemo } |- { $0.count } // {Some 1}
let dCount = cDemo |- { $0.subDemo } |- { $0.two() } // {Some 2}
println("\(aCount) \(bCount) \(cCount) \(dCount)")
//===== flatMap для Optional ======
extension Optional {
func flatMap<Z>(f:T->Z?) -> Z? {
switch self {
case .Some(let a):
return f(a)
case .None:
return .None
}
}
}
// ----- Тестовый пример 2 flatMap
let aCount1 = aDemo.flatMap { $0.subDemo }.flatMap { $0.count } // {None}
let bCount1 = bDemo.flatMap { $0.subDemo }.flatMap { $0.count } // {None}
let cCount1 = cDemo.flatMap { $0.subDemo }.flatMap { $0.count } // {Some 1}
println("\(aCount1) \(bCount1) \(cCount1)")
// ----- Тестовый пример 3 ?.
let aCount2 = aDemo?.subDemo?.count // {None}
let bCount2 = bDemo?.subDemo?.count // {None}
let cCount2 = cDemo?.subDemo?.count // {Some 1}
println("\(aCount2) \(bCount2) \(cCount2)")
// ----- Тестовый пример 4 flatMap
let a:Int? = 9 // some optional
if let a = a {
println("\(a)")
}
a.flatMap { println("\($0)") }
//==== Для статьи http://nomothetis.svbtle.com/implicitly-unwrapped-optionals-in-depth
// Подробнее об Implicitly Unwrapped Optionals (IUO)
// http://www.bestkora.com/SwiftLearning/podrobnee-ob-implicitly-unwrapped-optionals-iuo/ ‎
// ----- Тестовый пример 1
let arr:[String]! = ["hello", "world"]
let val = find(arr, "hello")
// ----- Тестовый пример 2
let str = "hello"
let a8 = str.stringByAppendingString("!")
let b8 = String.stringByAppendingString(str)("!")
let method = String.stringByAppendingString(str)
let c8 = method("!")
// ----- Тестовый пример 3
infix operator +- { associativity left precedence 150 }
func +-<T,Z>(obj:T, f:T->Z) -> Z {
return f(obj)
}
let happyHello1 = "hello" +- {
String.stringByAppendingString($0)("!")
}
// ----- Тестовый пример 4 оператор +-
infix operator +-= { associativity left precedence 150 }
func +-=<T,Z>(obj:ImplicitlyUnwrappedOptional<T>, f:T->Z)
-> ImplicitlyUnwrappedOptional<Z> {
switch obj {
case .Some(let x):
return f(x)
case .None:
abort()
}
}
let maybeHello:String! = "hello"
let happyHello8 = maybeHello +-= {
String.stringByAppendingString($0)("!")
} +-= {
String.stringByAppendingString($0)("!")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment