Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
I agree that curried functions are pretty odd at first. They definitely are an acquired taste! I’m not sure if I will find them useful in Swift, time will tell.
map — обычная монада, в которую вводятся данные и над которой производится цепочка вычислений. Это не значит, что всё нужно делать через нее — скорее думать головой и использовать ее там, где это действительно улучшило бы качество кода.map и не потерять в читаемости можно было бы вот так:getData().map({result in processData(result, scheme: someScheme)})
try {
float quotient = divide(1,0);
}
catch(ZeroDivisionException e) {
println("zero division");
}
Всегда был уверен, что сайд эффект — это когда функция делает что-то помимо возврата результата.
val m: Map[Int, Int]
def get(k: Int): Int {
var v = m.get(k)
if (v == null) {
v = /* pure calc */
m.put(k, v)
}
return v
}
Механизм исключений позволяет не вводить дополнительного возвращаемого типа, позволяет не вводить метод map и при этом писать понятный и простой код.
Также позволяет не писать в функциональном стиле, если тебе это не нравится и писать когда это приятно.
data Either a b = Left a | Right b
instance Functor (Either a) where
fmap _ (Left x) = Left x
fmap f (Right y) = Right (f y)
Either<A, B>. Это позволит нам вернуть пользователю объект как в случае, если все проходит успешно, так и в случае возникновения ошибки. В Swift можно так реализовать тип Either<A, B>:enum Either<A, B> {
case Left(A)
case Right(B)
}
Either<NSError, User> в качестве типа, который на финальном этапе преобразований может быть обработан так:switch either {
case let .Left(error):
// показываем сообщение об ошибке (error)
case let .Right(user):
// делаем что-то с user
}
Left всегда будет NSError. Result <A>, который будет содержать либо значение, которое мы ищем, либо ошибку. Его реализация выглядит так:enum Result<A> {
case Error(NSError)
case Value(A)
}
enum не могут быть дженериками (generic) на самом топовом уровне, но, могут быть представлены как generic, если их обернуть в «постоянный» class box:final class Box<A> {
let value: A
init(_ value: A) {
self.value = value
}
}
enum Result<A> {
case Error(NSError)
case Value(Box<A>)
}
result: Result <User> будет выглядеть так:switch result {
case let .Error(error):
// показываем сообщение об ошибке (error)
case let .Value(boxedUser):
let user = boxedUser.value
// делаем что-то с user
}
var v1: Int =0
var result1 = Result.Success(v1++)
result1.value // 0
result1.value // 1
Обработка ошибок в Swift — меч и магия