рдХреЛрдЯрд▓рд┐рди / рд╕реНрдХрд╛рд▓рд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдореБрдЭреЗ рдЬрд╛рд╡рд╛ рдореЗрдВ рдХреНрдпрд╛ рдпрд╛рдж рдЖрддрд╛ рд╣реИ

рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдореИрдВрдиреЗ рдЕрдХреНрд╕рд░ рд╕реБрдирд╛ рд╣реИ рдХрд┐ рдЬрд╛рд╡рд╛ рдПрдХ рдЕрдкреНрд░рдЪрд▓рд┐рдд рднрд╛рд╖рд╛ рдмрди рдЧрдИ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдмрдбрд╝реЗ рд╕рдорд░реНрдерд┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдореИрдВ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рд╕рд╣рдордд рдирд╣реАрдВ рд╣реВрдВред рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рднрд╛рд╖рд╛ рдЕрднреА рднреА рддреЗрдЬреА рд╕реЗ рдФрд░ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рдВрдЧрдард┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореИрдВ рдорд╛рдирддрд╛ рд╣реВрдБ, рдпрд╣ рднреА рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдЬрдм рдЖрдк рд╣рд░ рд░реЛрдЬрд╝ рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдХрднреА-рдХрднреА рд╕реЛрдЪрддреЗ рд╣реИрдВ: "рдХрд┐рддрдиреА рдЕрдЪреНрдЫреА рддрд░рд╣ рдпрд╣ рджреВрд╕рд░реА рднрд╛рд╖рд╛ рд╕реЗ рдЗрд╕ рдЪреАрдЬ рд╕реЗ рд╣рд▓ рд╣реЛрдЧрд╛"ред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдЕрдкрдиреЗ рджрд░реНрдж рдФрд░ рдЕрдиреБрднрд╡ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рд╣рдо рдХреБрдЫ рдЬрд╛рд╡рд╛ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рджреЗрдЦреЗрдВрдЧреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдХреЛрдЯрд▓рд┐рди / рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ рдХреИрд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рд╕рдорд╛рди рднрд╛рд╡рдирд╛ рд╣реИ рдпрд╛ рдЖрдк рд╕реЛрдЪ рд░рд╣реЗ рд╣реИрдВ рдХрд┐ рдЕрдиреНрдп рднрд╛рд╖рд╛рдПрдВ рдХреНрдпрд╛ рдкреЗрд╢рдХрд╢ рдХрд░ рд╕рдХрддреА рд╣реИрдВ, рддреЛ рдореИрдВ рдЖрдкрд╕реЗ рдмрд┐рд▓реНрд▓реА рдХреЗ рдиреАрдЪреЗ рдкреВрдЫрддрд╛ рд╣реВрдВред



рдореМрдЬреВрджрд╛ рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░


рдХрднреА-рдХрднреА рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдореМрдЬреВрджрд╛ рд╡рд░реНрдЧ рдХреЛ рдЙрд╕рдХреА рдЖрдВрддрд░рд┐рдХ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмрджрд▓реЗ рдмрд┐рдирд╛ рдЙрд╕рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдпрд╣реА рд╣реИ, рд╡рд░реНрдЧ рдмрдирд╛рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЗрд╕реЗ рдЕрдиреНрдп рд╡рд░реНрдЧреЛрдВ рдХреЗ рд╕рд╛рде рдкреВрд░рдХ рдХрд░рддреЗ рд╣реИрдВред рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╡рд░реНрдЧ рд╣реИ рдЬреЛ рджреЛ-рдЖрдпрд╛рдореА рдЕрдВрддрд░рд┐рдХреНрд╖ рдореЗрдВ рдПрдХ рдмрд┐рдВрджреБ рд╣реИред рд╣рдорд╛рд░реЗ рдХреЛрдб рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд╛рдиреЛрдВ рдкрд░, рд╣рдореЗрдВ рдЗрд╕реЗ Json рдФрд░ XML рджреЛрдиреЛрдВ рдореЗрдВ рдХреНрд░рдордмрджреНрдз рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рд╡рд┐рдЬрд╝рд┐рдЯрд░ рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдпрд╣ рдЬрд╛рд╡рд╛ рдореЗрдВ рдХреИрд╕реЗ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ
public class DotDemo { public static class Dot { private final int x; private final int y; public Dot(int x, int y) { this.x = x; this.y = y; } public String accept(Visitor visitor) { return visitor.visit(this); } public int getX() { return x; } public int getY() { return y; } } public interface Visitor { String visit(Dot dot); } public static class JsonVisitor implements Visitor { @Override public String visit(Dot dot) { return String .format("" + "{" + "\"x\"=%d, " + "\"y\"=%d " + "}", dot.getX(), dot.getY()); } } public static class XMLVisitor implements Visitor { @Override public String visit(Dot dot) { return "<dot>" + "\n" + " <x>" + dot.getX() + "</x>" + "\n" + " <y>" + dot.getY() + "</y>" + "\n" + "</dot>"; } } public static void main(String[] args) { Dot dot = new Dot(1, 2); System.out.println("-------- JSON -----------"); System.out.println(dot.accept(new JsonVisitor())); System.out.println("-------- XML ------------"); System.out.println(dot.accept(new XMLVisitor())); } } 

рдкреИрдЯрд░реНрди рдФрд░ рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ

рдпрд╣ рдХрд╛рдлреА рдмрдбрд╝рд╛, рд╕рд╣реА рд▓рдЧ рд░рд╣рд╛ рд╣реИ? рдХреНрдпрд╛ рднрд╛рд╖рд╛ рдХреЗ рдФрдЬрд╛рд░реЛрдВ рдХреА рдорджрдж рд╕реЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдЕрдзрд┐рдХ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдврдВрдЧ рд╕реЗ рд╣рд▓ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ? рд╕реНрдХрд╛рд▓рд╛ рдФрд░ рдХреЛрдЯрд▓рд┐рди рдиреЗ рд╕рдХрд╛рд░рд╛рддреНрдордХ рд░реВрдк рд╕реЗ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ред рдпрд╣ рд╡рд┐рдзрд┐ рд╡рд┐рд╕реНрддрд╛рд░ рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИред

рдХреЛрдЯрд▓рд┐рди рдореЗрдВ рдПрдХреНрд╕рдЯреЗрдВрд╢рди
 data class Dot (val x: Int, val y: Int) //      fun Dot.convertToJson(): String = "{\"x\"=$x, \"y\"=$y}" fun Dot.convertToXml(): String = """<dot> <x>$x</x> <y>$y</y> </dot>""" fun main() { val dot = Dot(1, 2) println("-------- JSON -----------") println(dot.convertToJson()) println("-------- XML -----------") println(dot.convertToXml()) } 


рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ рдПрдХреНрд╕рдЯреЗрдВрд╢рди
 object DotDemo extends App { // val is default case class Dot(x: Int, y: Int) implicit class DotConverters(dot: Dot) { def convertToJson(): String = s"""{"x"=${dot.x}, "y"=${dot.y}}""" def convertToXml(): String = s"""<dot> <x>${dot.x}</x> <y>${dot.y}</y> </dot>""" } val dot = Dot(1, 2) println("-------- JSON -----------") println(dot.convertToJson()) println("-------- XML -----------") println(dot.convertToXml()) } 


рдпрд╣ рдмрд╣реБрдд рдмреЗрд╣рддрд░ рд▓рдЧ рд░рд╣рд╛ рд╣реИред рдХрднреА-рдХрднреА рдпрд╣ рдмрд╣реБрддрд╛рдпрдд рд╕реЗ рдорд╛рдирдЪрд┐рддреНрд░рдг рдФрд░ рдЕрдиреНрдп рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд╕рд╛рде рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред

рдорд▓реНрдЯреА-рдереНрд░реЗрдбреЗрдб рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдЪреЗрди


рдЕрдм рд╣рд░ рдХреЛрдИ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдереНрд░реЗрдбреНрд╕ рдореЗрдВ рд▓реЙрдХрд┐рдВрдЧ рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣рд╛ рд╣реИред рдЖрдЗрдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдорд╕реНрдпрд╛ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ: рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рдХрдИ рд╕реНрд░реЛрдд рд╣реИрдВ, рдЬрд╣рд╛рдБ рдкрд╣рд▓рд╛ рдХреЗрд╡рд▓ рд╕рдВрдЦреНрдпрд╛ рджреЗрддрд╛ рд╣реИ, рджреВрд╕рд░рд╛ - рдкрд╣рд▓реЗ рдХреА рдЧрдгрдирд╛ рдХреЗ рдмрд╛рдж рдЙрддреНрддрд░ рджреЗрддрд╛ рд╣реИред рдирддреАрдЬрддрди, рд╣рдореЗрдВ рджреЛ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдпреЛрдЬрдирд╛рдмрджреНрдз рд░реВрдк рд╕реЗ, рдЗрд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ


рдЖрдЗрдП рдкрд╣рд▓реЗ рдЬрд╛рд╡рд╛ рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ

рдЬрд╛рд╡рд╛ рдЙрджрд╛рд╣рд░рдг
  private static CompletableFuture<Optional<String>> calcResultOfTwoServices ( Supplier<Optional<Integer>> getResultFromFirstService, Function<Integer, Optional<Integer>> getResultFromSecondService ) { return CompletableFuture .supplyAsync(getResultFromFirstService) .thenApplyAsync(firstResultOptional -> firstResultOptional.flatMap(first -> getResultFromSecondService.apply(first).map(second -> first + " " + second ) ) ); } 


рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдкрд░рд┐рдгрд╛рдо рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реА рд╕рдВрдЦреНрдпрд╛ рд╡реИрдХрд▓реНрдкрд┐рдХ рдореЗрдВ рд▓рд┐рдкрдЯреА рд╣реБрдИ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдереНрд░реЗрдбреНрд╕ рдХреЗ рд╕рд╛рде рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдХрд╛рдо рдХреЗ рд▓рд┐рдП рдХрдВрдкреНрд▓реАрдЯреЗрдмрд▓рдлреНрдпреВрд╡рди рдХреЗ рдЕрдВрджрд░ рд╕рднреА рдХреНрд░рд┐рдпрд╛рдПрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВред рдореБрдЦреНрдп рдХреНрд░рд┐рдпрд╛ рддрддреНрдХрд╛рд▓реАрдиApplyAsync рд╡рд┐рдзрд┐ рдореЗрдВ рд╣реЛрддреА рд╣реИред рдЗрд╕ рдкрджреНрдзрддрд┐ рдореЗрдВ, рд╣рдо рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реИрдХрд▓реНрдкрд┐рдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рдЕрдЧрд▓рд╛, рд╕рдВрджрд░реНрдн рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлреНрд▓реИрдЯрдкрд╛рдЗрдк рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдкреНрд░рд╛рдкреНрдд рд╡реИрдХрд▓реНрдкрд┐рдХ Optional.empty рдХреЗ рд░реВрдк рдореЗрдВ рд▓реМрдЯрд╛ рд╣реИ, рддреЛ рд╣рдо рджреВрд╕рд░реА рд╕реЗрд╡рд╛ рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдПрдВрдЧреЗред

рдХреБрд▓ рдЬреЛ рд╣рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖ? рд╕рдореНтАНрдорд┐рд▓рди рдФрд░ рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рд╕рд╛рде рдХрдВрдкреНтАНрд▓реАрдЯрдЯреЗрдмрд▓ рд╕рд┐рд╡рдиреА рдФрд░ рдСрдкреНтАНрд╢рдирд▓ рдлреАрдЪрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╣рдо рдЗрд╕ рд╕рдорд╕реНтАНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдереЗред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рд╕рдорд╛рдзрд╛рди рд╕рдмрд╕реЗ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рддрд░реАрдХреЗ рд╕реЗ рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИ: рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдЖрдк рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рдорд╛рдорд▓рд╛ рдХреНрдпрд╛ рд╣реИ, рдЖрдкрдХреЛ рдХреЛрдб рдкрдврд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдФрд░ рджреЛ рдпрд╛ рдЕрдзрд┐рдХ рдбреЗрдЯрд╛ рд╕реНрд░реЛрддреЛрдВ рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рд╣реЛрдЧрд╛?

рдХреНрдпрд╛ рднрд╛рд╖рд╛ рдХрд┐рд╕реА рддрд░рд╣ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рд╣рдорд╛рд░реА рдорджрдж рдХрд░ рд╕рдХрддреА рд╣реИред рдФрд░ рдлрд┐рд░, рд╕реНрдХрд╛рд▓рд╛ рдХреА рдУрд░ рдореБрдбрд╝реЗрдВред рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕реЗ рд╕реНрдХреИрд▓рд╛ рдЯреВрд▓реНрд╕ рд╕реЗ рдХреИрд╕реЗ рд╣рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╕реНрдХрд╛рд▓рд╛ рдЙрджрд╛рд╣рд░рдг
 def calcResultOfTwoServices(getResultFromFirstService: Unit => Option[Int], getResultFromSecondService: Int => Option[Int]) = Future { getResultFromFirstService() }.flatMap { firsResultOption => Future { firsResultOption.flatMap(first => getResultFromSecondService(first).map(second => s"$first $second" ) )} } 


рдпрд╣ рдкрд░рд┐рдЪрд┐рдд рд▓рдЧ рд░рд╣рд╛ рд╣реИред рдФрд░ рдпрд╣ рдХреЛрдИ рд╕рдВрдпреЛрдЧ рдирд╣реАрдВ рд╣реИред рдпрд╣ scala.concurrent рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ java.concurrent рдкрд░ рдПрдХ рдЖрд╡рд░рдг рд╣реИред рдЦреИрд░, рд╕реНрдХрд╛рд▓рд╛ рд╣рдорд╛рд░реА рдФрд░ рдХреНрдпрд╛ рдорджрдж рдХрд░ рд╕рдХрддреА рд╣реИ? рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдлреЙрд░реНрдо рдлреНрд▓реИрдЯрдкреИрди, ..., рдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЛ рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреНрд░рдо рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рд╕реНрдХрд╛рд▓рд╛ рдкрд░ рджреВрд╕рд░рд╛ рд╕рдВрд╕реНрдХрд░рдг рдЙрджрд╛рд╣рд░рдг
  def calcResultOfTwoServices(getResultFromFirstService: Unit => Option[Int], getResultFromSecondService: Int => Option[Int]) = Future { getResultFromFirstService() }.flatMap { firstResultOption => Future { for { first <- firstResultOption second <- getResultFromSecondService(first) } yield s"$first $second" } } 


рдпрд╣ рдмреЗрд╣рддрд░ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдЗрдП рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрджрд▓рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред рдмрд┐рд▓реНрд▓рд┐рдпреЛрдВ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВред

рд╕реНрдХрд╛рд▓рд╛ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рддреАрд╕рд░рд╛ рд╕рдВрд╕реНрдХрд░рдг
 import cats.instances.future._ def calcResultOfTwoServices(getResultFromFirstService: Unit => Option[Int], getResultFromSecondService: Int => Option[Int]): Future[Option[String]] = (for { first <- OptionT(Future { getResultFromFirstService() }) second <- OptionT(Future { getResultFromSecondService(first) }) } yield s"$first $second").value 


рдЕрдм рдпрд╣ рдЗрддрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ рдХрд┐ OptionT рдХрд╛ рдЕрд░реНрде рдХреНрдпрд╛ рд╣реИред рдореИрдВ рд╕рд┐рд░реНрдл рдпрд╣ рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдСрдкрд░реЗрд╢рди рдХрд┐рддрдирд╛ рд╕рд░рд▓ рдФрд░ рдЫреЛрдЯрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рд▓реЗрдХрд┐рди рдХреЛрдЯрд▓рд┐рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛? рдЖрдЗрдП рдХреЛрд░рдЯрд╛рдЗрди рдкрд░ рдХреБрдЫ рдРрд╕рд╛ рд╣реА рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВред

рдХреЛрдЯрд▓рд┐рди рдХрд╛ рдЙрджрд╛рд╣рд░рдг
 val result = async { withContext(Dispatchers.Default) { getResultFromFirstService() }?.let { first -> withContext(Dispatchers.Default) { getResultFromSecondService(first) }?.let { second -> "$first $second" } } } 


рдЗрд╕ рдХреЛрдб рдХреА рдЕрдкрдиреА рдЦрд╝рд╛рд╕рд┐рдпрддреЗрдВ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рдХреЙрд░рдЯрд┐рди рдХреЗ рдХреЛрдЯрд▓рд┐рди рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред Async рдХреЗ рдЕрдВрджрд░ рдХрд╛рд░реНрдп рдПрдХ рд╡рд┐рд╢реЗрд╖ рдереНрд░реЗрдб рдкреВрд▓ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдлреЛрд░реНрдХрдЬреЙрдЗрди рдирд╣реАрдВ) рдПрдХ рдХрд╛рдо рдЪреЛрд░реА рддрдВрддреНрд░ рдХреЗ рд╕рд╛рдеред рджреВрд╕рд░реЗ, рдЗрд╕ рдХреЛрдб рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╕рдВрджрд░реНрдн рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕реЗ async рдФрд░ withContext рдЬреИрд╕реЗ рдХреАрд╡рд░реНрдб рд▓рд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

рдпрджрд┐ рдЖрдкрдХреЛ рд╕реНрдХрд╛рд▓рд╛ рдлреНрдпреВрдЪрд░ рдкрд╕рдВрдж рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рдХреЛрдЯрд▓рд┐рди рдкрд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЗрд╕реА рддрд░рд╣ рдХреЗ рд╕реНрдХреИрд▓ рд░реИрдкрд░ рдкрд░ рдзреНрдпрд╛рди рджреЗ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕реЗ рдЯрд╛рдЗрдк рдХрд░реЗрдВред

рдзрд╛рд░рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ


рд╕рдорд╕реНрдпрд╛ рдХреЛ рдКрдкрд░ рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ: рд╣рдо рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рдЬрд╛рд╡рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдЯреВрд▓реНрд╕ - рд░рд┐рдПрдХреНрдЯрд░ , рд╕реНрдХрд╛рд▓рд╛ - рдПрдлрдПрд╕ 2 рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ ред

рдПрдХ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ 3 рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд╛рдЗрди-рдмрд╛рдп-рд▓рд╛рдЗрди рд░реАрдбрд┐рдВрдЧ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдФрд░ рд╡рд╣рд╛рдВ рдореИрдЪ рдЦреЛрдЬрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред
рдпрд╣рд╛рдБ рдЬрд╛рд╡рд╛ рдореЗрдВ рд░рд┐рдПрдХреНрдЯрд░ рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рд╣реИред

рдЬрд╛рд╡рд╛ рдореЗрдВ рд░рд┐рдПрдХреНрдЯрд░ рдЙрджрд╛рд╣рд░рдг
  private static Flux<String> glueFiles(String filename1, String filename2, String filename3) { return getLinesOfFile(filename1).flatMap(lineFromFirstFile -> getLinesOfFile(filename2) .filter(line -> line.equals(lineFromFirstFile)) .flatMap(lineFromSecondFile -> getLinesOfFile(filename3) .filter(line -> line.equals(lineFromSecondFile)) .map(lineFromThirdFile -> lineFromThirdFile ) ) ); } 


рд╕рдмрд╕реЗ рдЗрд╖реНрдЯрддрдо рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд╛рдВрдХреЗрддрд┐рдХ рд╣реИред рдпрд╣ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИ рдХрд┐ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдореЗрдВ рдЕрдзрд┐рдХ рддрд░реНрдХ рдФрд░ рдкрд╣реБрдВрдЪ рдХреЗ рд╕рд╛рде, рдХреЛрдб рдХреА рдЬрдЯрд┐рд▓рддрд╛ рдмрдврд╝реЗрдЧреАред рдЖрдЗрдП, рдлреЙрд░-рдХреЙрдореНрдкреНрд░рд┐рд╣реЗрдВрд╢рди рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╢реБрдЧрд░ рд╡рд┐рдХрд▓реНрдк рджреЗрдЦреЗрдВред

Scala рдкрд░ fs2 рд╕реЗ рдЙрджрд╛рд╣рд░рдг
  def findUniqueLines(filename1: String, filename2: String, filename3: String): Stream[IO, String] = for { lineFromFirstFile <- readFile(filename1) lineFromSecondFile <- readFile(filename2).filter(_.equals(lineFromFirstFile)) result <- readFile(filename3).filter(_.equals(lineFromSecondFile)) } yield result 


рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдмрджрд▓рд╛рд╡ рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рдмреЗрд╣рддрд░ рджрд┐рдЦрддрд╛ рд╣реИред

рдЙрдЪреНрдЪ рддрд░реНрдХ рдФрд░ рдирд┐рд╣рд┐рдд рдХреЗ рд╕рд╛рде рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХ рдХреЛ рдЕрд▓рдЧ рдХрд░рдирд╛


рдЖрдЗрдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ рдФрд░ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рдФрд░ рдХреИрд╕реЗ рд╕реБрдзрд╛рд░ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВ рдЪреЗрддрд╛рд╡рдиреА рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдЕрдЧрд▓рд╛ рднрд╛рдЧ рддреБрд░рдВрдд рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖ рд╕рдХрддрд╛ рд╣реИред рдореИрдВ рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХреЛ рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдФрд░ рдЕрдм рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рдзрд┐ рдХреЛ рдХреЛрд╖реНрдардХ рд╕реЗ рдмрд╛рд╣рд░ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реВрдВред рд╡рд┐рд╕реНрддреГрдд рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП рдХрдо рд╕реЗ рдХрдо рдПрдХ рдЕрд▓рдЧ рд▓реЗрдЦ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрджрд┐ рдХреЛрдИ рдЗрдЪреНрдЫрд╛ / рдЯрд┐рдкреНрдкрдгреА рд╣реИ - рддреЛ рдореИрдВ рдкреНрд░рд╢реНрдиреЛрдВ рдХрд╛ рдЙрддреНрддрд░ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЕрдиреБрд╕рд░рдг рдХрд░реВрдВрдЧрд╛ рдФрд░ рджреВрд╕рд░рд╛ рднрд╛рдЧ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддреГрдд рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рд▓рд┐рдЦреВрдВрдЧрд╛ :)

рдЗрд╕рд▓рд┐рдП, рдПрдХ рдРрд╕реА рджреБрдирд┐рдпрд╛ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рд╡рд┐рдХрд╛рд╕ рдХреЗ рджреМрд░рд╛рди рдЙрддреНрдкрдиреНрди рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рддрдХрдиреАрдХреА рдкреНрд░рднрд╛рд╡реЛрдВ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдж рдХреЗ рдЕрдиреБрд░реЛрдз рдХреЛ DBMS рдпрд╛ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреА рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдереНрд░реЗрдб рдореЗрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ, рд╣рдореЗрдВ рдПрдХ рдмреЗрд╡рдХреВрдл рдореЙрдХ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдФрд░ рдЗрд╕реА рддрд░рд╣ред

рд╢рд╛рдпрдж рдХреБрдЫ рд▓реЛрдЧреЛрдВ рдиреЗ BPM рдЗрдВрдЬрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЖрдЬ рдпрд╣ рдЙрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╣реИред рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдФрд░ рднрд╛рд╖рд╛ рд╕рдорд░реНрдерди рдХреЗ рдХреБрдЫ рдкреИрдЯрд░реНрди рдХреА рдорджрдж рд╕реЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдПрдХ рдЬрдЧрд╣ рд╣рдо рдЗрд╕ рддрд░рд╣ рдХреЗ рддрд░реНрдХ рдХрд╛ рд╡рд░реНрдгрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдПрдХ рдЬрдЧрд╣, рд╣рдо рдЗрд╕ рддрд░рд╣ рдХреЗ рддрд░реНрдХ рдХрд╛ рд╡рд░реНрдгрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
  def makeCatHappy[F[_]: Monad: CatClinicClient](): F[Unit] = for { catId <- CatClinicClient[F].getHungryCat memberId <- CatClinicClient[F].getFreeMember _ <- CatClinicClient[F].feedCatByFreeMember(catId, memberId) } yield () 


рдпрд╣рд╛рдВ рдПрдл [_] ("рдПрдлрд╝ рд╡рд┐рдж рдП рд╣реЛрд▓" рдХреЗ рд░реВрдк рдореЗрдВ рдкрдврд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ) рдХрд╛ рдЕрд░реНрде рд╣реИ рдПрдХ рдкреНрд░рдХрд╛рд░ рдкрд░ рдПрдХ рдкреНрд░рдХрд╛рд░ (рдХрднреА-рдХрднреА рдЗрд╕реЗ рд░реВрд╕реА рд╕рд╛рд╣рд┐рддреНрдп рдореЗрдВ рдкреНрд░рдЬрд╛рддрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ)ред рдпрд╣ рд╕реВрдЪреА, рд╕реЗрдЯ, рд╡рд┐рдХрд▓реНрдк, рднрд╡рд┐рд╖реНрдп, рдЖрджрд┐ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд╣ рд╕рдм рдПрдХ рдЕрд▓рдЧ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рдХрдВрдЯреЗрдирд░ рд╣реИред

рдЕрдЧрд▓рд╛, рд╣рдо рд╕рд┐рд░реНрдл рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдареЗрд╕ рдХреЗ рдорд╛рд╣реМрд▓ рдХреЗ рд▓рд┐рдП рд╣рдо рдХреБрдЫ рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдореБрдХрд╛рдмрд▓рд╛ рдХреЛрдб рдХреИрд╕рд╛ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ?
 class RealCatClinicClient extends CatClinicClient[Future] { override def getHungryCat: Future[Int] = Future { Thread.sleep(1000) // doing some calls to db (waiting 1 second) 40 } override def getFreeMember: Future[Int] = Future { Thread.sleep(1000) // doing some calls to db (waiting 1 second) 2 } override def feedCatByFreeMember(catId: Int, memberId: Int): Future[Unit] = Future { Thread.sleep(1000) // happy cat (waiting 1 second) println("so testy!") // Don't do like that. It is just for debug } } 


рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдХреИрд╕рд╛ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ
 class MockCatClinicClient extends CatClinicClient[Id] { override def getHungryCat: Id[Int] = 40 override def getFreeMember: Id[Int] = 2 override def feedCatByFreeMember(catId: Int, memberId: Int): Id[Unit] = { println("so testy!") // Don't do like that. It is just for debug } } 


рд╣рдорд╛рд░рд╛ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдЕрдм рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╣рдордиреЗ рдХрд┐рди рдлреНрд░реЗрдорд╡рд░реНрдХ, http-рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИред рдХрд┐рд╕реА рднреА рд╕рдордп, рд╣рдо рд╕рдВрджрд░реНрдн рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЙрдкрдХрд░рдг рдмрджрд▓ рдЬрд╛рдПрдЧрд╛ред

рдЗрд╕реЗ рд╣рд╛рдпрд░рдХрд┐рдВрдб рдФрд░ рдЗрдВрдкреИрдХреНрдЯ рдЬреИрд╕реЗ рдлреАрдЪрд░реНрд╕ рд╕реЗ рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЖрдЗрдП рдкрд╣рд▓реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ, рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдо рдЬрд╛рд╡рд╛ рдкрд░ рд▓реМрдЯреЗрдВрдЧреЗред

рдХреЛрдб рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ
 public class Calcer { private CompletableFuture<Integer> getCalc(int x, int y) { } } 


рдкрд░рд┐рдгрд╛рдо рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рдХрд┐рддрдиреЗ рддрд░реАрдХреЗ рд╣реИрдВ? рдХрд╛рдлреА рдХреБрдЫред рд╣рдо рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рд╕реНрд╡реИрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдм рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рд╣рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рджреА рдЧрдИ рд╣реИрдВред рд╣рдореЗрдВ рдкрд╣рд▓реЗ рдирдВрдмрд░ рдХреЛ рджреВрд╕рд░реЗ рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдо рдЗрд╕реЗ рдХрд┐рддрдиреЗ рддрд░реАрдХреЛрдВ рд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдпрджрд┐ рдЖрдк рдХрдбрд╝реА рдореЗрд╣рдирдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдиреЗ рдЖрдк рдХреЛ рдмрд╣реБрдд рдкрд░рд┐рд╖реНрдХреГрдд рдХрд░рддреЗ рд╣реИрдВ ... рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдХреЗрд╡рд▓ рдПрдХред

рдпрд╣рд╛рдБ рд╡рд╣ рд╣реИ
 public class Calcer { private CompletableFuture<Integer> getCalc(int x, int y) { return CompletableFuture.supplyAsync(() -> x + y); } } 


рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдЗрд╕ рдкрджреНрдзрддрд┐ рдХрд╛ рдХреЙрд▓ рдЫрд┐рдкрд╛ рд╣реБрдЖ рд╣реИ, рдФрд░ рд╣рдо рдПрдХ рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ? рдпрд╛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рд╣рдо рдХрдВрдкреНрд▓реАрдЯрдЯреЗрдмрд▓ рд╕рд┐рд╡рдиреА рдХреЛ рд╣рдЯрд╛рдХрд░ / рдмрджрд▓рдХрд░ рдХрдХреНрд╖рд╛ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЬрд╛рд╡рд╛ рдореЗрдВ рд╣рдо рд╢рдХреНрддрд┐рд╣реАрди рд╣реИрдВ рдФрд░ рд╡рд┐рдзрд┐ рдПрдкреАрдЖрдИ рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ рд╡рд┐рдХрд▓реНрдк рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред

рд╡рд┐рд╢реЗрд╖рддрд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ
 trait Calcer[F[_]] { def getCulc(x: Int, y: Int): F[Int] } 


рд╣рдо рдЕрдкрдиреЗ рдкреВрд░реНрдгрд╛рдВрдХ рдорд╛рди рдХреЗ рдХрдВрдЯреЗрдирд░ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдП рдмрд┐рдирд╛ рд▓рдХреНрд╖рдг (рдирд┐рдХрдЯрддрдо рдПрдирд╛рд▓реЙрдЧ рдЬрд╛рд╡рд╛ рдореЗрдВ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ) рдмрдирд╛рддреЗ рд╣реИрдВред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рддреЛ рд╣рдо рдмрд╕ рд╡рд┐рднрд┐рдиреНрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдРрд╕реЗ рд╣реА
  val futureCalcer: Calcer[Future] = (x, y) => Future {x + y} val optionCalcer: Calcer[Option] = (x, y) => Option(x + y) 


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, Implicit рдЬреИрд╕реА рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рд╣рдорд╛рд░реЗ рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рдмрдирд╛рдиреЗ рдФрд░ рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдРрд╕реЗ рд╣реА
  def userCalcer[F[_]](implicit calcer: Calcer[F]): F[Int] = calcer.getCulc(1, 2) def doItInFutureContext(): Unit = { implicit val futureCalcer: Calcer[Future] = (x, y) => Future {x + y} println(userCalcer) } doItInFutureContext() def doItInOptionContext(): Unit = { implicit val optionCalcer: Calcer[Option] = (x, y) => Option(x + y) println(userCalcer) } doItInOptionContext() 


рд╡реИрд▓ рд╕реЗ рдкрд╣рд▓реЗ рд╕рд░рд▓реАрдХреГрдд рдирд┐рд╣рд┐рддрд╛рд░реНрде - рд╡рд░реНрддрдорд╛рди рдкрд░рд┐рд╡реЗрд╢ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪрд░ рдЬреЛрдбрд╝рдирд╛, рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд╣рд┐рдд рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдкрд░реНрдпрд╛рд╡рд░рдг рд╕реЗ рдЪрд░ рд▓реЗрдирд╛ред рдпрд╣ рдХреБрдЫ рд╣рдж рддрдХ рдПрдХ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдмрдВрдж рдХреА рдпрд╛рдж рджрд┐рд▓рд╛рддрд╛ рд╣реИред

рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рд╣рдо рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛ рдПрдХ рдореБрдХрд╛рдмрд▓рд╛ рдФрд░ рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред
рд▓реЗрдХрд┐рди рдХреЛрдЯрд▓рд┐рди рдХрд╛ рдХреНрдпрд╛
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕реА рддрд░рд╣ рд╕реЗ рд╣рдо рдХреЛрдЯрд▓рд┐рди рдореЗрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
 interface Calculator<T> { fun eval(x: Int, y: Int): T } object FutureCalculator : Calculator<CompletableFuture<Int>> { override fun eval(x: Int, y: Int) = CompletableFuture.supplyAsync { x + y } } object OptionalCalculator : Calculator<Optional<Int>> { override fun eval(x: Int, y: Int) = Optional.of(x + y) } fun <T> Calculator<T>.useCalculator(y: Int) = eval(1, y) fun main() { with (FutureCalculator) { println(useCalculator(2)) } with (OptionalCalculator) { println(useCalculator(2)) } } 

рдпрд╣рд╛рдВ рд╣рдо рдЕрдкрдиреЗ рдХреЛрдб рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдВрджрд░реНрдн рднреА рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕реНрдХрд╛рд▓рд╛ рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╣рдо рдЗрд╕реЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддреЗ рд╣реИрдВред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рджреЗрдЦрдиреЗ рд╡рд╛рд▓реЗ рдХрд╛ рдзрдиреНрдпрд╡рд╛рджред


рдирд┐рд╖реНрдХрд░реНрд╖


рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдпреЗ рдореЗрд░реЗ рд╕рд╛рд░реЗ рджрд░реНрдж рдирд╣реАрдВ рд╣реИрдВред рдФрд░ рднреА рд╣реИрдВред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдбреЗрд╡рд▓рдкрд░ рдХрд╛ рдЕрдкрдирд╛ рд╣реИред рдЕрдкрдиреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдХрд┐ рдореБрдЦреНрдп рдмрд╛рдд рдпрд╣ рд╕рдордЭрдирд╛ рд╣реИ рдХрд┐ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд╛рдн рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпрд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдпрджрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЖрд░рд╛рдо рд╕реЗрд╡рд╛ рд╣реИ рдЬреЛ рдорд╛рдирдЪрд┐рддреНрд░рдг рдФрд░ рд╕рд░рд▓ рддрд░реНрдХ рдХреЗ рдЧреБрдЪреНрдЫрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдбрд╛рдкреНрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рддреА рд╣реИ, рддреЛ рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рдирд╣реАрдВ рд╣реИред рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ + рдЬрд╛рд╡рд╛ / рдХреЛрдЯрд▓рд┐рди рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХрджрдо рд╕рд╣реА рд╣реИред рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдПрдХреАрдХрд░рдг рдФрд░ рдХреБрдЫ рдЬрд╛рдирдХрд╛рд░реА рдПрдХрддреНрд░ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдЕрдиреНрдп рдорд╛рдорд▓реЗ рд╣реИрдВред рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдЕрдВрддрд┐рдо рд╡рд┐рдХрд▓реНрдк рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рд╣реИред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдпрджрд┐ рдЖрдк рдХрд┐рд╕реА рдХрд╛рд░реНрдп рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЙрдкрдХрд░рдг рдХрд╛ рдЪрдпрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддреЛ рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реИред

рдЙрдкрдпреЛрдЧреА рд╕рдВрд╕рд╛рдзрди:

  1. рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рдкреВрд░реНрдг рдЙрджрд╛рд╣рд░рдгреЛрдВ рд╕реЗ рд▓рд┐рдВрдХ рдХрд░реЗрдВ
  2. рдХреЛрдЯрд▓рд┐рди рдореЗрдВ рдХреЛрд░реЛрдЯрд┐рди рдкрд░ рдЕрдзрд┐рдХ
  3. рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдкрд░ рдПрдХ рдЕрдЪреНрдЫреА рдкрд░рд┐рдЪрдпрд╛рддреНрдордХ рдкреБрд╕реНрддрдХ

Source: https://habr.com/ru/post/hi456774/


All Articles