ááŒá®ážáá²á·áá²á· ááœá±áá¬áá®ááŸá¬ áá»áœááºáá±á¬áº áá«áááºáá²á·áá«áááºá
Google Summer of Code 2019 ááœáẠáá«áááºáá°áá
áºáŠážá¡áá±ááŒáá·áº á
á¬ááŒáá·áºááá¯ááºá¡ááœááºáž ááá±á¬áá»ááºáá
áºáá¯ááᯠáá¯ááºáá²á·áá«áááºá
ဠpost ááœáẠHaskell ááœáẠááŸá áºáááºáá®ááŒááºážá¡ááœáẠááááºááá¯á á áºáá±ážááŒááºážá¡ááœáẠáá»áœááºá¯ááºá á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááá¯ááºáᬠalgorithm á¡ááŒá±á¬ááºážááŒá±á¬áá«áááºá algorithm ááẠá¡ááŒá±áá¶á¡áá»áá¯á¶ážáá»á¬ážáá²á០áá áºáá¯ááŒá áºáá±á¬áºáááºážá áááºážááᯠfunctional style ááŒáá·áº ááŸáá áœá¬ á¡áá±á¬ááºá¡áááºáá±á¬áºááŒááºážááẠáá»áœááºá¯ááºá¡á¬áž áááºáá«áááºáá« á¡ááŒáááºáá±á«ááºážáá»á¬ážá áœá¬ áá¯ááºáá²á·áááŒá®áž á¡áá¯ááºáá»á¬ážá áœá¬ ááá¯á¡ááºáá«áááºá ááá¯á·ááŒá±á¬áá·áº áá»áœááºá¯ááºááẠmonad ááááºá áá±á¬áºáá¬áá»á¬ážááŒáá·áº á¡áá±á¬ááºá¡áááºáá±á¬áºááẠáá¯á¶ážááŒááºáá²á·áááºá
ááá¯áá·áºá¡ááŒá±á¬ááºážááá¯ááº
áá»áœááºá¯ááºá¡ááẠVasily Alferov ááŒá
áºáá«áááºá áá»áœááºá¯ááºááẠá
ááá·áºáá®áá¬á
ááẠHSE ááœáẠá
áá¯áá¹áááŸá
Ạáá»á±á¬ááºážáá¬ážááŒá
áºáááºá á
á±á¬á
á±á¬á ááá±á¬á·ááŸá¬ áá±ážáááºá
algorithm áá¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááŸáá·áº áááºáááº
á áá¬ážáá»á®áž
áááá¯ááááºááœáẠáá«áááºááá·áº áá»á±á¬ááºážáá¬ážáá»á¬ážá¡á¬áž ááá±á¬á·ááºááá¯á· ááŒááºážááŒááºážáááºááẠá¡á¬ážáá±ážáá«áááºá áá°ááá¯á·á ááá±á¬á·ááºá¡ááœáẠááááºáá±á¬ááºážáá
áºáᯠáá±ážáá¬ážáááºá
Pull Request ááœáẠáá±ážááœááºážá¡ááœáẠáá¯ááºááŒáá·áº ááœá±á·ááá¯ááºáááºá
áá»áœááºá¯ááºáá¡áá¯ááºáááááºáá»á¬ážá¡ááŒá±á¬ááºáž (á¡ááºá¹áááááºáá¬áá¬ááŒáá·áºáááºááá¯ááºáááº)
ဠpost ááẠfunctional programming ááœááºá¡ááŒá±áá¶ááá±á¬ááá¬ážáá»á¬ážááŸáá·áºá á¬áááºáá°á¡á¬ážáááºážááŸá®ážá á±áááºáááºááœááºáááºá ááá¯á·áá±á¬áºá¡áá»áááºáá±á¬ááºáá±á¬á¡áá«á¡áá¯á¶ážááŒá¯áá±á¬áá±á«áá¬áá¡á¬ážáá¯á¶ážááá¯ááŒááºáááºááááºážáááºážáááºááŒáá¯ážá á¬ážáá«áááºá
ááŸá áºáááºáá®ááŒááºážá¡ááœáẠááááºáá»á¬ážááᯠá á áºáá±ážááŒááºážá
á¡ááá¯ážááŸááºážáá¯á¶áž ááááºá¡ááºááºááá¯áá®áááºáá»á¬ážáá²á០áá áºáá¯á¡ááŒá Ạalgorithms ááá¯ááºáᬠáááºáááºážáá áºáá¯ááœáẠááááºááŸá áºáá¯áá«áááºááŸá¯ááᯠá á áºáá±ážááŒááºážá¡ááœáẠalgorithm ááᯠáá±ážáá±á·ááŸááááºá áá°áá¡ááŒá¶á¡á ááºááẠááá¯ážááá¯ážááŸááºážááŸááºážááŒá áºáááº- ááááŠážá áœá¬ áá»áœááºá¯ááºááá¯á·ááẠáááºááẠááá¯á·ááá¯áẠáá¬áááºáá±á á¯ááœáẠáá±á«ááºááá¯ááºáá»á¬ážááᯠáá áºáááºážáááºážááŒáá·áº ááá·áºáᬠááœá²ááœá²áá±áá±á¬á¡á áœááºážáá áºáá¯ááᯠááœá±á·ááŸááá±á¬á¡áá«á ááááºááẠááŸá áºáááºááá¯ááºááŒá±á¬ááºáž á¡ááá¯ááºá¡áá¬ááá¯áááºá
áá±á¬ááºáááºá¡áá±ážá áááºá¡áá»ááºáá áºáá»ááº- ááááŠážá áœá¬ áá»áœááºá¯ááºááá¯á·ááẠáááºáááºáá±á á¯ááœáẠááááºáááºážá¡áá»áá¯á·ááᯠááá·áºáá¬ážáááºá áááá¬áááºááŸá¬ážáááºá ဠvertex áá¡áááºáá®ážáá»ááºážáá»á¬ážá¡á¬ážáá¯á¶ážááẠáá¬áááºá¡ááŒáŸá±ážááœáẠá¡áááºáá±ááááºááŒá áºáááºá ááá¯á·á¡ááŒááºá á€ááááºáááºážáá¡áááºáá®ážáá»ááºážáá»á¬ážáá¡áááºáá®ážáá»ááºážáá»á¬ážá¡á¬ážáá¯á¶ážáááºáááºáááºá¡ááŒáŸá±ážááœááºá¡áááºááááºá á áááºááá¯á·ááŒá áºáááºá á¡áááºáá®ážáá¬ážáá»ááºážáá»á¬ážááᯠááááºááŸááºááá±ážáá±á¬ áá±á«ááºááá¯ááºááá»áááºáááºáá¬ážáá±á¬á¡á áááºá¡ááá¯ááºážááœáẠáá±á«ááºááá¯ááºáá»á¬ážááŸááá±áá±ážáááœá±á· áá»áœááºá¯ááºááá¯á·ááẠá¡á á¯ááŸááºáá¬áá»á¬ážááᯠáááºáááºáááºááŸááºáá±ážáá«áááºá ááá¯á·áá±á¬áẠáá»áááºáááºáá¬ážáá±á¬ á¡á áááºá¡ááá¯ááºážá¡á¬ážáá¯á¶ážá¡ááœáẠá€áá¯ááºáá±á¬ááºáá»ááºááᯠáááºáá¯ááºáá«áááºá
áá°áá®áá±á¬á¡áááºážááá·áºááá¯á· áá»áá±á¬ááºáá±ááá·áº áá±á«ááºááá¯ááºáá»á¬ážááŒá¬ážááœáẠá¡á áœááºážáá áºáá¯ááŸááá±áá«áá bipartite ááááºááœáẠáá»ááºááŒáá·áºá áœá¬ááááŸáááá¯ááºáá±á¬ (áááºááŸá¬ážááŒá®áž) áááŒá áºááá¯ááºáá±á¬ ááááºááŸá áá°ážáááºážáá±á¬á ááºááá¯ááºážááᯠááŸá¬ááœá±ááẠááááºáá²áá«á ááá¯ááºáá«áá áá»áœááºá¯ááºááá¯á·ááœáẠááŸááºáááºáá±á¬ partition áá áºáá¯ááŸááááºá ááá¯ááá¯áááºááŸá¬ ááááºááẠbipartite ááŒá áºáááºá
áá¯á¶ááŸááºá¡á¬ážááŒáá·áºá ဠalgorithm ááᯠá¡áá¯á¶ážááŒá¯á á¡áá±á¬ááºá¡ááẠáá±á¬áºáááºá
ááá¯á·ááŒá±á¬áá·áº áá»áœááºá¯ááºááá¯á·ááẠá¡á±á¬ááºáá«á¡á á®á¡á á¥áºááá¯á· áá±á¬ááºááŸááá¬áá«áááºá áá»áœááºá¯ááºááá¯á·ááẠá¡ááááºá¡áááº-áááááŸá¬ááœá±ááŸá¯ááᯠá¡áá¯á¶ážááŒá¯á ááááºáá»á¬ážá áá±á«ááºááá¯ááºáá»á¬ážááᯠááŒááºáᬠáááºážááá¯á·áᶠáá»áŸáá±ááŸá¯áá»á¬áž áááºááŸááºáá±ážáᬠá¡á áœááºážáá áºáá»áŸá±á¬áẠááœá±á·áá»á¬ážááá·áºá¡áá« áá»áŸáá±ááŸá¯á¡áá±á¡ááœááºááᯠááŒá±á¬ááºážáá²áá±ážáá«áááºá á¡á á¯ááŸááºáá¬áá áºáᯠáááºááŸááºáá±ážáá¬ážááŒá®ážááŒá áºáá±á¬ ááááºáááºážááá¯á· áá»áŸáá±ááẠááŒáá¯ážá á¬ážáá«áá ááááºááẠááŸá áºáááºáááºááá¯ááºááŒá±á¬ááºáž áá¯á¶ááŒá¯á¶á áœá¬ááŒá±á¬ááá¯ááºáááºá áá±á«ááºááá¯ááºá¡á¬ážáá¯á¶ážááᯠá¡á á¯ááŸááºáá¬áá áºáᯠáááºááŸááºááŒá®áž á¡á áœááºážá¡á¬ážáá¯á¶ážááᯠááŒáá·áºááŸá¯ááŒá®ážááá·áºá¡ááá¯ááºááœááºá áá»áœááºá¯ááºááá¯á·ááœáẠá¡ááá¯ááºážááá¯ááºážáá±á¬ááºážáá áºáá¯ááŸááááºá
ááœááºáá»ááºááŸá¯áááá·áºááŸááºážááŸá¯
Haskell ááœáẠáá»áœááºá¯ááºááá¯á·ááẠááœááºáá»ááºááŸá¯á¡á¬ážáá¯á¶ážááŒá áºáááºáᯠáá»áœááºá¯ááºááá¯á·áá°ááááºá ááá·áºááŸááºážá ááá¯á·áá±á¬áºá á€á¡áá¬ááẠá¡ááŸááºááááºááŒá áºáá²á·áá«áá áá»áœááºá¯ááºááá¯á·ááẠáá»ááºááŸá¬ááŒááºáá±á«áºááœáẠáááºááá·áºá¡áá¬ááá¯áá»áŸ áááá·áºáá¯ááºááẠáááºážáááºážááŸááááºááá¯ááºáá«á áá¯á¶ážáá ááá·áºááŸááºážáá±á¬ ááœááºáá»ááºááᬠáá»ááºážááœááºážááá¯á· áá áºáá¯á០áááŸááá°ážá ááá·áºááŸááºáž áá áºá á¯á¶áá áºáá¯ááᯠááœááºáá»ááºááẠá¡ááŒá±á¬ááºážááŒáá»ááºáá»á¬ážá áááá¯ááááºááœáẠááŒá áºáá±á«áºáá±ááá·áº ááœááºáá»ááºááŸá¯á¡á¬ážáá¯á¶ážááᯠáá áºáááºážáááºážááŒáá·áº ááá¯ááºážá á±áá«áááºá "áááá·áºááŸááºáž" monad IOá
Monads ááẠááœááºáá»ááºááŸá¯áá»á¬ážááᯠááá¯ááºá
á¬ážááŒá¯ááá·áº áááºážáááºážáá
áºáá¯ááŒá
áºáááºá ááá¯ážáá»áá¯ážáá»á¬áž Haskell ááœááºá áá°ááá¯á·áááºááá¯á¡áá¯ááºáá¯ááºáááºááá¯áá¬ááᯠááŸááºážááŒáá¬á áá®ááá¯á·á
áºáá²á· áá±á¬ááºááá¯áá»á±á¬áºááœááºáá«áááºá áá±á¬ááºážááœááºááŸááºážáááºážáá±á¬ áá±á¬áºááŒáá»ááºááᯠá¡ááºá¹áááááºáá¬áá¬ááŒáá·áº áááºááŸá¯ááá¯ááºáá«áááºá
á€áá±áá¬ááœáẠIO áá²á·ááá¯á· á¡áá»áá¯á·áá±á¬ monads áá»á¬ážááᯠcompiler magic ááŒáá·áº á¡áá±á¬ááºá¡áááºáá±á¬áºáá±áá±á¬áºáááºážá á¡ááŒá¬ážá¡áá¬á¡á¬ážáá¯á¶ážáá®ážáá«ážááᯠsoftware ááŒáá·áºá¡áá±á¬ááºá¡áááºáá±á¬áºááŒá®áž áááºážááá¯á·ááœááºááŸááá±á¬ ááœááºáá»ááºááŸá¯á¡á¬ážáá¯á¶ážááẠááá·áºááŸááºážááŒá±á¬ááºážááᯠá€áá±áá¬ááœáẠáá±á¬ááºááŒááá¯áá«áááºá
á¡áá»áá¯ážáááºáá±á¬ááºááŸá¯áá»á¬ážáá»á¬ážá áœá¬ááŸáááŒá®ážáá áºáá¯á á®ááœááºáááºážáááá¯ááºááá¯áẠmonad ááŸááááºá á€áááºááŸá¬ á¡ááœááºá¡á¬ážáá±á¬ááºážááŒá®áž ááŸááá±á¬áá®á¡áá¯áá®áá áºáá¯ááŒá áºáááº- monads á¡á¬ážáá¯á¶ážááẠáá°áá®áá±á¬áá»ááºááŸá¬ááŒááºááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºáááºá á¡á±á¬ááºáá±á¬áºááŒáá« áá¯ááºážááŒá®ážáá¯á¶ážáá«ážá¡ááŒá±á¬ááºážááᯠááŒá±á¬ááŒáá«áááºá
- ea ááẠtype a ááááºááá¯ážááá¯ááŒááºáá±ážááẠááá¯á·ááá¯áẠtype e áááŒáœááºážáá»ááºáá áºáá¯ááŒá áºáááºá ဠmonad áá¡ááŒá¯á¡áá°ááẠááŒáœááºážáá»ááºáááŸááááŒá áºááá¯á¡ááºáá±á¬áá¬áá¬á áá¬ážáá»á¬ážááŒáá·áº ááá¯ááºááœááºááŒááºážááŸáá·áº á¡ááœááºáááºáá°áá«áááº- á¡ááŸá¬ážáá»á¬ážááá¯áááºážááááá¯ááºááẠááá¯á·ááá¯áẠáá±ážááá¯á·ááá¯ááºáá«áááºá á¡áááááœá¬ááŒá¬ážáá»ááºááŸá¬ monad ááẠHaskell ááŸá á á¶á á¬ááŒáá·áºááá¯ááºááœáẠáá¯á¶ážááá¯áá¹áááááºážáá»ááŒáá·áº á¡áá±á¬ááºá¡áááºáá±á¬áºáá¬ážááŒá®ážá ááá¯á¡ááºáá±á¬áá¬áá¬á áá¬ážáá»á¬ážááẠáá¯á¶ááŸááºá¡á¬ážááŒáá·áº áááºáááºááŸá¯á áá áºááá¹ááá¬ážáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯áá«áááºá
- State sa ááẠá¡áá»áá¯ážá¡á á¬áž a ááááºááá¯ážááᯠááŒááºáá±ážáᬠá¡áá»áá¯ážá¡á á¬áž s ááᯠááŒá±á¬ááºážáá²ááá¯ááºáá±á¬ á¡ááŒá±á¡áá±ááá¯á· áááºáá±á¬ááºááá¯ááºáá±á¬ ááœááºáá»ááºááŸá¯áá áºáá¯ááŒá áºáááºá
- ááŒá áºááá¯ááºáááºá May monad ááẠNoth ááá¯ááŒááºáá±ážááŒááºážááŒáá·áº á¡áá»áááºáááœá±áž á¡ááŸá±á¬ááºá¡ááŸááºááŒá áºá á±ááá¯ááºáá±á¬ ááœááºáá»ááºááŸá¯ááᯠáá±á¬áºááŒáááºá ááá¯á·áá±á¬áºá ááá·áºáá»ááºáááºá¡áá»áá¯ážáááºáá±á¬ááºááŸá¯ááá¯áá±á¬áºááŒááá·áº Maybe á¡áá»áá¯ážá¡á á¬ážá¡ááœáẠMonadPlus á¡áááºážááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááŒááºážá¡ááŒá±á¬ááºáž áá»áœááºá¯ááºááá¯á·ááŒá±á¬ááá¯áá«áááº- áááºážááẠáááá»áá±á¬áááºááá¯ážááᯠááŒááºáá±ážááŒááºážááŒáá·áº á¡áá»áááºáááœá±áž á¡ááŸá±á¬áá·áºá¡ááŸááºááŒá áºá á±ááá¯ááºáá±á¬ ááœááºáá»ááºááŸá¯áá áºáá¯ááŒá áºáááºá
algorithm ááá¯á¡áá±á¬ááºá¡áááºáá±á¬áºááŒááºážá
áá»áœááºá¯ááºááá¯á·ááœáẠáá±áá¬á¡áá»áá¯ážá¡á á¬ážááŸá áºáá»áá¯ážááŒá áºááá·áº Graph a ááŸáá·áº Bigraph ab ááŸáááŒá®áž ááááá áºáá»áá¯ážááŸá¬ a ááááºááá¯ážáá»á¬ážáᯠá¡ááœáŸááºážáááºáá¬ážáá±á¬ ááááºáá»á¬ážááᯠááá¯ááºá á¬ážááŒá¯ááŒá®áž áá¯áááá¡áá»áá¯ážá¡á á¬ážááŸá¬ a ááŸáá·áº áá¬áááºááœáẠáááºááá¯ážáá»á¬ážáá¶ááááºáááºáá¬ážáá±á¬ áááºáááºááŒááºážááŸá ááááºáá áºáá»á¬ážááᯠááá¯ááºá á¬ážááŒá¯ááẠá¡áá»áá¯ážá¡á á¬áž b ááááºááá¯ážáá»á¬ážááŒáá·áºáá¶ááááºáááºáá¬ážáá±á¬ -side verticesá
áááºážááá¯á·ááẠAlga á á¬ááŒáá·áºááá¯ááºá០á¡áá»áá¯ážá¡á á¬ážáá»á¬ážááá¯ááºáá«á Alga ááœáẠáááºážááœáŸááºááá¬ážáá±á¬ ááŸá áºááá¯ááºážááááºáá»á¬ážá¡ááœáẠááá¯ááºá á¬ážááŒá¯ááŸá¯ áááŸááá«á áá®ááá¯áá»áá¯áž á¡áá»áá¯ážá¡á á¬ážááœá±ááᯠááŸááºážááŸááºážáááºážáááºážááŒá áºá¡á±á¬áẠáá¯ááºáá¬ážáááºá
á¡á±á¬ááºáá±á¬áºááŒáá« áááºááŸááºáá»á¬ážááŒáá·áº á¡áá°á¡áá®áá±ážááá·áº áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážáááºáž ááá¯á¡ááºáá«áááºá
-- СпОÑПк ÑПÑеЎей ЎаММПй веÑÑОМÑ.
neighbours :: Ord a => a -> Graph a -> [a]
-- ÐПÑÑÑПОÑÑ ÐŽÐ²ÑЎПлÑÐœÑй гÑÐ°Ñ Ð¿ÐŸ гÑаÑÑ Ðž ÑÑМкÑОО, ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ¹ веÑÑОМÑ
-- вÑЎаÑÑей ÐµÑ ÐŽÐŸÐ»Ñ Ðž пПЌеÑÐºÑ Ð² МПвПй ЎПле, ОгМПÑОÑÑÑ ÐºÐŸÐœÑлОкÑÐœÑе ÑÑбÑа.
toBipartiteWith :: (Ord a, Ord b, Ord c) => (a -> Either b c)
-> Graph a
-> Bigraph b c
-- СпОÑПк веÑÑОМ в гÑаÑе
vertexList :: Ord a => Graph a -> [a]
СОгМаÑÑÑа ÑÑМкÑОО, кПÑПÑÑÑ ÐŒÑ Ð±ÑЎеЌ пОÑаÑÑ, вÑглÑÐŽÐžÑ Ñак:
type OddCycle a = [a]
detectParts :: Ord a => Graph a -> Either (OddCycle a) (Bigraph a a)
áááºááŸáá¯ááºážáá±á¬ áááááŸá¬ááœá±ááŸá¯ááœáẠááœá²ááœá²áá±áá±á¬á¡á áœááºážáá áºáá¯ááᯠáá»áœááºá¯ááºááá¯á·ááœá±á·ááŸááá«áá áá°ážáááºážáá±á¬á ááºáááºážááẠááŒááºáááºáá¯á á¬ážááŸá¯á¡á á¯áááááºááœáẠááŸááá±áááºááᯠááááŒááºáááºááŸá¬ ááœááºáá°áá«áááºá ááá¯á·ááŒá±á¬áá·áºá áááºážááᯠááŒááºáááºááá°áááºá áá»áœááºá¯ááºááá¯á·ááẠááŒááºáááºáá¯áá¯á¶ážá¡á ááºážá០áá±á¬ááºáá¯á¶ážááááºáááºážá ááááá¯á¶ážááŒá áºáá±á«áºááŸá¯á¡áá á¡áá¬á¡á¬ážáá¯á¶ážááᯠááŒááºáá±á¬ááºááẠááá¯á¡ááºáááºá
áá»áœááºá¯ááºááá¯á·ááẠááááºáááºážáá áºáá¯á á®á¡ááœáẠááœá²áá±ááááºážááááºážáá»á¬áž áá±á«ááºážá ááºáá¬ážáá±á¬ á¡áááºážá¡áá»ááºážááᯠááááºážááááºážááŒááºážááŒáá·áº á¡áááº-áááááŸá¬ááœá±ááŸá¯ááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºáááºá áá»áœááºá¯ááºááá¯á·ááœá±ážáá»ááºáá¬ážáá±á¬ monad á Functor á¡áááºážá¡á á¬ážááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááŒááºážááŒáá·áº recursion stack ááẠá¡ááá¯á¡áá»á±á¬ááºááááºážááááºážáá¬ážáááá·áºáááº- áá»áœááºá¯ááºááá¯á·ááẠrecursive function á០ááŒááºáá¬áá±á¬ááááºá¡ááŒá ẠáááºážááŒá±á¬ááºážá០vertices á¡á¬ážáá¯á¶ážááᯠááá·áºáááºáá¬ááá¯áá«áááºá
áá»áœááºá¯ááºáááááá¯á¶ážá áááºáá°ážááŸá¬ áá»áœááºá¯ááºááá¯á·ááá¯á¡ááºáá±á¬á¡áá»áá¯ážáááºáá±á¬ááºááŸá¯áá»á¬ážááᯠá¡ááá¡áá»á¡áá±á¬ááºá¡áááºáá±á¬áºáá¯á¶áá±á«áºááá·áº Either monad ááá¯á¡áá¯á¶ážááŒá¯áááºááŒá áºáááºá áá»áœááºáá±á¬áºáá±ážáá²á·áá²á· ááááá¯á¶ážá¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯á áá®ááœá±ážáá»ááºááŸá¯áá²á· á¡áááºážáá®ážá ááºáá«áááºá ááááºáá±á¬á·á áá áºááŒáááºááŸá¬ ááá°áá®áá²á· á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ áá«ážáá¯ááŸááá²á·ááŒá®áž áá±á¬ááºáá¯á¶ážááŸá¬áá±á¬á· áá±á¬ááºáá áºáá¯á¡áá±á«áº á¡ááŒá±áá»áá²á·áááºá
ááááŠážá
áœá¬á áá»áœááºá¯ááºááá¯á·ááẠááœá²áá±áááºááŸááºááŒááºážááá¯ááºáᬠáááºá
ááºááŸá¯áááºážáá»á¬ážááᯠááááºážááááºážáá¬ážááẠááá¯á¡ááºááẠ- áááºážááẠááá¯ááºáá¶áá±á¬áºááŸáá·áº áááºáááºááá·áº á¡áá¬áá
áºáá¯ááŒá
áºáááºá áá¯áááá¡áá±áá²á·á áááááá¹ááá
áºáá¯ááᯠááœá±á·ááŸááá²á·á¡áá« áááºááá·áºááá¯ááºááá¯á·ááá¯áá«áááºá áááºážááẠMonad for Either ááá¯á·ááá¯áẠMonadPlus for Maybe ááŒá
áºááá¯ááºáááºá á¡ááá ááœá¬ááŒá¬ážáá»ááºááŸá¬ ááœááºáá»ááºááŸá¯ ááááºááá·áºáá«á ááŸá
áºáá¯áá¯á¶ážááẠáááºááá¯ážáá
áºáá¯ááᯠááŒááºáá±ážááá¯ááºááẠááŒá
áºááŒá®áž á€ááá
á¹á
ááœáẠáááºážááŸáá·áºáááºáááºááá·áº á¡áá»ááºá¡áááºááá¯áᬠááŒááºáá±ážááá¯ááºáááºá áá»áœááºá¯ááºááá¯á·ááẠá¡á±á¬ááºááŒááºááŸá¯á¡ááœáẠáá®ážááŒá¬ážáááºááá¯ážááᯠáááá¯á¡ááºáá±á¬ááŒá±á¬áá·áº (áááºážááᯠááá¯ááºáá¶áá±á¬áºááœáẠááááºážáááºážáá¬ážááŒá®ážááŒá
áºáááº)á áá»áœááºá¯ááºááá¯á·ááẠMaybe ááᯠááœá±ážáá»ááºáá«áááºá áá¯ááºážááŒá®ážááŸá
áºáá«ážá á¡áá»áá¯ážáááºáá±á¬ááºááŸá¯ááᯠáá±á«ááºážá
ááºááẠááá¯á¡ááºáá±á¬á¡áá«ááœáẠáááºážááá¯á·ááẠááœááºáá±á«áºáá¬áááºá
áá®ááá¯ááŸá¯ááºááœá±ážáá²á· á¡áá»áá¯ážá¡á á¬ážááᯠáá¬ááŒá±á¬áá·áº ááœá±ážáá»ááºáá²á·áá¬áá²á á¡ááŒá±á¬ááºážáááºážááŸá áºáá¯á ááááŠážá áœá¬á á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááẠááá¯á¡ááºáá»ááºááŸáá·áº á¡ááœááºáááºáá°áá«áááºá áá¯áááá¡áá±ááŒáá·áºá Maybe monad ááœááºáá¯ááºáá±á¬ááºáááºááá¯ááá¯ááœááºáá°ááá·áº odd loop ááá¯ááŒááºáááºááá°áááºá¡ááœáẠrecursion ááŸááŒááºáá¬ááá·áºá¡áá« áááááá¹áááŒá áºááá·áºá¡áá« return value ááᯠááá¯ááºááœááºááẠááá¯á¡ááºáá«áááºá
áá«ááŒá±á¬áá·áº áá®á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááᯠáá»áœááºáá±á¬áºááá¯á· áááŸááá«áááºá
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE ScopedTypeVariables #-}
data Part = LeftPart | RightPart
otherPart :: Part -> Part
otherPart LeftPart = RightPart
otherPart RightPart = LeftPart
type PartMap a = Map.Map a Part
type OddCycle a = [a]
toEither :: Ord a => PartMap a -> a -> Either a a
toEither m v = case fromJust (v `Map.lookup` m) of
LeftPart -> Left v
RightPart -> Right v
type PartMonad a = MaybeT (State (PartMap a)) [a]
detectParts :: forall a. Ord a => Graph a -> Either (OddCycle a) (Bigraph a a)
detectParts g = case runState (runMaybeT dfs) Map.empty of
(Just c, _) -> Left $ oddCycle c
(Nothing, m) -> Right $ toBipartiteWith (toEither m) g
where
inVertex :: Part -> a -> PartMonad a
inVertex p v = ((:) v) <$> do modify $ Map.insert v p
let q = otherPart p
msum [ onEdge q u | u <- neigbours v g ]
{-# INLINE onEdge #-}
onEdge :: Part -> a -> PartMonad a
onEdge p v = do m <- get
case v `Map.lookup` m of
Nothing -> inVertex p v
Just q -> do guard (q /= p)
return [v]
processVertex :: a -> PartMonad a
processVertex v = do m <- get
guard (v `Map.notMember` m)
inVertex LeftPart v
dfs :: PartMonad a
dfs = msum [ processVertex v | v <- vertexList g ]
oddCycle :: [a] -> [a]
oddCycle c = tail (dropWhile ((/=) last c) c)
block ááẠalgorithm á core ááŒá áºáááºá á¡áá²ááŸá¬ áá¬ááœá±ááŒá áºáá±áá² ááŸááºážááŒááá¯á· ááŒáá¯ážá á¬ážáá«á·áááºá
- inVertex ááẠáááá¡ááŒááẠvertex ááᯠáá»áœááºá¯ááºááá¯á·ááœá¬ážáá±á¬ááºááŒáá·áºááŸá¯ááá·áº á¡áááº-áááááŸá¬ááœá±ááŸá¯á á¡á áááºá¡ááá¯ááºážááŒá áºáááºá á€áá±áá¬ááœáẠáá»áœááºá¯ááºááá¯á·ááẠááŸááºáá¬áá¶áá«ááºáá áºáá¯ááᯠvertex ááá¯á·áááºááŸááºááŒá®áž á¡áááºáá®ážáá»ááºážá¡á¬ážáá¯á¶ážááœáẠonEdge ááá¯ááœáá·áºáá«á á€áá±áá¬ááœáẠáá»áœááºá¯ááºááá¯á·ááẠáá±á«áºááá¯ááŸá¯á¡á á¯ááᯠááŒááºáááºááá°ááá·áºáá±áá¬ááŒá áºáááºá á¡áááºá msum ááẠáááºááá¯ážáá áºáá¯ááᯠááŒááºáá±ážáááºááá¯áá«áá áá»áœááºá¯ááºááá¯á·ááẠvertex v ááᯠááá¯áá±áá¬ááá¯á· ááœááºážááá¯á·áá«áááºá
- onEdge ááẠáá»áœááºá¯ááºááá¯á· á¡á áœááºážááá¯á· ááœá¬ážáá±á¬ááºááá·áº á¡ááá¯ááºážááŒá áºáááºá á¡á áœááºážáá áºáá¯á á®á¡ááœáẠááŸá áºááŒáááºáá±á«áºáááºá á€áá±áá¬ááœáẠáá»áœááºá¯ááºááá¯á·ááẠáá áºáááºááŸá ááááºáááºážááᯠáá±á¬ááºáá²á·áááºááŸááááŸá á á áºáá±ážááŒá®áž ááá¯ááºáá«á áááºážááᯠááœá¬ážáá±á¬ááºááŒáá·áºááŸá¯áá«á á¡áááºáá¬áá«áá á¡á áœááºážááẠááœá²ááœá²ááŸá¯ááŸááááŸá á á áºáá±ážáá«áááºá á¡áááºá ááá¯ááá¯á·ááŒá áºáá«áá áá»áœááºá¯ááºááá¯á·ááẠáááºááá¯ážááᯠááŒááºáá±ážááẠ- ááá¯á·áá±á¬áẠá¡ááŒá¬áž áá±á«ááºááá¯ááºáá»á¬ážá¡á¬ážáá¯á¶ážááᯠááŒááºá áá¬ážááŸáááá·áº recursion stack á ááááºááá¯ááºážá
- processVertex ááẠvertex áá áºáá¯á á®ááᯠáááºáááºááŒá®áž ááá¯ááºáá«á áááºážáá±á«áºááœáẠVertex ááœáẠá¡áá¯ááºáá¯ááºáááºááŸááááŸá á á áºáá±ážáááºá
- dfs ááẠáá±á¬áá·áºá¡á¬ážáá¯á¶ážááœáẠprocessVertex ááᯠáá¯ááºáá±á¬ááºáááºá
áá«áá«áá²á
INLINE áá°áá±á¬ á áá¬ážáá¯á¶ážáááá¯ááºáž
INLINE áá°áá±á¬ á áá¬ážáá¯á¶ážááẠá¡ááºáááá¯áá®áááºá ááááá¯á¶ážá¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááœááºááá¯ááºáá«á áá±á¬ááºááá¯ááºážááœááºáá±á«áºáá¬áááºá ááá¯ááá¯áá±á¬ááºážááœááºáá±á¬ á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááᯠááŸá¬ááœá±á·áá±á¬á¡áá«á INLINE ááá¯ááºáá±á¬áá¬ážááŸááºážááẠá¡áá»áá¯á·áá±á¬ááááºáá»á¬ážááœáẠáááááá¬áᬠááŸá±ážááœá±ážááœá¬ážáááºááᯠááœá±á·áá²á·ááááºá ááá±á¬ááá¬ážá¡á áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááẠáá°áá®ááá·áºáááºáᯠáá°ááá«áá á€á¡áá¬ááẠáá»áœááºá¯ááºá¡á¬áž á¡ááœááºá¡á¶á·ááŒáááá«áááºá áá°á áááºážáá±á¬ááºááŸá ááá°áá®áá²á· GHC áá¬ážááŸááºážááŸááá²á· á¡ááŒá¬ážá ááºááŸá¬ áááá¬áááºááŸá¬ážáá²á· ááœá¬ááŒá¬ážááŸá¯áááŸááá«áá°ážá
GHC Core áá¯ááºáá±ážááŸá¯ááᯠáá áºáááºááŒá¬áááºááŸá¯ááŒá®ážáá±á¬ááºá ááŒááºáá¬ážáá±á¬ INLINE áá áºááŒá±á¬ááºážááŒáá·áº ááŒá¿áá¬ááᯠááŒá±ááŸááºážááá¯ááºáá²á·áááºá GHC 8.4.4 ááŸáá·áº GHC 8.6.5 ááŒá¬áž áá áºáá»áááºáá»áááºááœáẠááá¯ááá¯áá±á¬ááºážááœááºá¡á±á¬ááºááŒá¯áá¯ááºáá°ááẠáááºážááᯠáááºážáááá¯ááºááá¯ááºáá¯ááºáá±á¬ááºááŸá¯ááᯠáááºááœá¬ážáá²á·áááºá
Haskell áááá¯ááááºážáááºážááœáẠááá¯ááá¯á·áá±á¬ á¡áá áºá¡ááŒá±ážáá»á¬ážááᯠááŒá¯á¶ááœá±á·ááááºáᯠáá»áœááºá¯áẠááá»áŸá±á¬áºááá·áºáá²á·áá«á ááá¯á·áá±á¬áºáááºáž ááá±á·ááœááºáááºá optimizers áá»á¬ážááẠáá áºáá«áá áºáá¶ááœáẠá¡ááŸá¬ážáá»á¬ážááŒá¯áá¯ááºááŒááŒá®áž áááºážááá¯á·á¡á¬áž á¡ááááºá¡ááŒáœááºáá±ážáááºá¡ááœáẠáá»áœááºá¯ááºááá¯á·áá¡áá¯ááºááŒá áºáááºá á¥ááá¬á¡á¬ážááŒáá·áºá áááºážááẠimperative áá¬ážááŸááºážááœáẠáá»ááºážáá¬ážáá¬ážáá±á¬ááŒá±á¬áá·áº function ááᯠinline áá¯ááºááá·áºáááºááᯠá€áá±áá¬ááœáẠáá»áœááºá¯ááºááá¯á·áááááŒá®ážá áááºážááẠcompiler á¡á¬áž á¡ááááºá¡ááŒáœááºáá±ážááẠá¡ááŒá±á¬ááºážááŒáá»ááºáá áºáá¯ááŒá áºáááºá
áá¬áááºááŒá áºáá¬áá²á
ááá¯á·áá±á¬áẠHopcroft-Karp algorithm ááᯠá¡ááŒá¬áž monads áá»á¬ážááŸáá·áº á¡áá±á¬ááºá¡áááºáá±á¬áºáá²á·ááŒá®ážá áááºážááẠáááá¯ááááºá á¡áá¯á¶ážááŒá áºáááºá
Google Summer of Code ááá»á±ážáá°ážááŒá±á¬áá·áºá Functional Programming ááœáẠáááºááœá±á·áá»áá±á¬ á¡ááœá±á·á¡ááŒá¯á¶ááᯠáááŸááá²á·ááŒá®áž áááºážááẠáá±á¬ááºááœá±áá¬áá®ááœáẠJane Street ááœáẠá¡áá¯ááºáááºáááºážááẠáá°áá®áá±ážáá¯á¶áá¬áá (á€áá±áá¬ááẠHabr á áááºáá»áœááºážáá¬ážáááºáá° ááááááºááŒá¬ážááœááºááẠáááºáá»áŸáá°áááá»á¬ážááẠááááá±á¬áºáááºáž áááºážááŸá¬ áá
áºáá¯á¡áá«á¡áááºááŒá
áºáááºá á¡áá¯ááºáá¯ááºáá²á· áááá¯ááááºážáááºážááŸá¬ áá«áááºááá¯á· ááœá±áá¬áá®ááŸá¬ áááºáá¯ááºááá¯ááºáá²á· á¡áááºážáááºáá²á)á áá«áá±ááá·áº áá®áá«áá¬ááá¯ááºážááᯠáááºááœá±á·áá»áá·áºáá¯á¶ážáá²á· á¡á¶á·ááœááºááá¹áá¬ááŒá®ážááá¯áááºáž ááááºáááºáá±ážáá²á·ááŒá®ážá áá»áœááºáá±á¬á·áºáá²á· ááá¯ážáá¬áá¬áá¬á
áá¬ážáá²á· á¡ááœá±á·á¡ááŒá¯á¶áá²á· áááááá¬áᬠááœá¬ááŒá¬ážáá«áááºá
source: www.habr.com