ããã¯ãããã°ã©ãã·ãªãŒãºã®ã«ããŽãªçè«ã®7çªç®ã®èšäºã§ãã 以åã®èšäºã¯ãã§ã«Habréã§å
¬éãããŠããŸãã
ãã¡ã³ã¯ã¿ãŒ
ãã¡ã³ã¯ã¿ãŒã®æŠå¿µã®èåŸã«ã¯ãéåžžã«ã·ã³ãã«ã§ãããªãã匷åãªã¢ã€ãã¢ããããŸãïŒã©ã®ããã«ããã¯ãããŠããããã«èãããŠãïŒã åãªãã«ããŽãªãŒçè«ã¯ãã·ã³ãã«ã§åŒ·åãªã¢ã€ãã¢ã«æºã¡ãŠããŸãã ãã¡ã³ã¯ã¿ãŒã¯ãã«ããŽãªãŒéã®ãããã³ã°ã§ãã 2ã€ã®ã«ããŽãªCãšDãäžãããããã¡ã³ã¯ã¿ãŒFãCã®ãªããžã§ã¯ããDã®ãªããžã§ã¯ãã«ãããã³ã°ãããšããŸã-ããã¯ãªããžã§ã¯ãã«å¯Ÿãã颿°ã§ãã aãCããã®ãªããžã§ã¯ãã§ããå Žåã Dããã®ç»åãF a ïŒæ¬åŒ§ãªãïŒã§ç€ºããŸãã ãã ããã«ããŽãªã¯ãªããžã§ã¯ãã ãã§ãªããããããã€ãªãå°ã§ããããŸãã ãã¡ã³ã¯ã¿ã¯å°ã衚瀺ããŸã-ããã¯å°ã«å¯Ÿãã颿°ã§ãã ããããå°ã¯ã©ã³ãã ã«è¡šç€ºãããã®ã§ã¯ãªããæ¥ç¶ãç¶æãããããªæ¹æ³ã§è¡šç€ºãããŸãã ã€ãŸããCã®å°fããªããžã§ã¯ãaãšãªããžã§ã¯ãbãé¢é£ä»ããå Žåã
f :: a -> b
次ã«ãDã®fã®ç»åF f㯠ã aã®ç»åãšbã®ç»åãæ¥ç¶ããŸãã
F f :: F a -> F b
ïŒæ°åŠè¡šèšãšHaskellæ§æã®ãã®ãããªæ··åç©ãèªè
ã«çè§£ã§ããããšãé¡ã£ãŠããŸãããªããžã§ã¯ããŸãã¯å°ã«ãã¡ã³ã¯ã¿ãŒãé©çšããããšã§æ¬åŒ§ãæžããŸãããïŒ

ã芧ã®ããã«ããã¡ã³ã¯ã¿ãŒã¯æ§é ãä¿æããŸããå
¥åã«ããŽãªã§æ¥ç¶ãããŠãããã®ã¯ãåºåã§ãæ¥ç¶ãããŸãã ããããæ§é ã¯ããã«éå®ãããŸããïŒå°ã®åæããµããŒãããããšãå¿
èŠã§ãã h
ãf
ãšg
åæã§f
g
ïŒ
次ã«ãFã®äœçšäžã®ç»åãç»åfãšgã®åæã§ããããšãå¿
èŠã§ãã
F h = F g . F f

æåŸã«ãCããã®ãã¹ãŠã®ãŠãããïŒåäžæ§ïŒå°ãDããã®ãŠãããå°ã«ãããã³ã°ãããå¿
èŠããããŸãã
F id(a) = id(F a)
ããã§ã id aã¯ãªããžã§ã¯ãaã®åäœå°ã§ããã id F aã¯ãªããžã§ã¯ãF aã®åäœå°ã§ãã

ãããã®æ¡ä»¶ã¯ãã¹ãŠãå°ãšããŠé©ãã颿°ã®ç¯å²ã倧å¹
ã«å¶éããããšã«æ³šæããŠãã ããã ãã¡ã³ã¯ã¿ãŒã¯ãã«ããŽãªãŒã®æ§é ãç¶æããå¿
èŠããããŸãã ã«ããŽãªãŒãå°ãšæ··ããåã£ããªããžã§ã¯ãã®ã»ãããšããŠæ³åãããšããã¡ã³ã¯ã¿ãŒã¯ãã®ã¬ãŒã¹ã®åäžã®ç³žãåãæš©å©ãæã¡ãŸããã è€æ°ã®ãªããžã§ã¯ããçµã¿åãããããšãã§ããã¢ãŒãã£ãºã ã1ã€ã«çµã³ä»ããããšãã§ããŸãããçµã³ä»ããå£ãããšã¯ãããŸããã ãã®å¶éã¯ãæ°åŠçåæã®é£ç¶æ§ã®æŠå¿µã«äŒŒãŠããŸãã ãã®æå³ã§ããã¡ã³ã¯ã¿ãŒã¯ãé£ç¶çãã§ãïŒãã ãããã¡ã³ã¯ã¿ãŒã®é£ç¶æ§ã«ã¯ããã«å¶éçãªå®çŸ©ããããŸãïŒã ä»ã®é¢æ°ãšåæ§ã«ããã¡ã³ã¯ã¿ãŒã¯æ¥çãŸãã¯ãã¹ãã§ããŸãã æè³ã®åŽé¢ã¯ããœãŒã¹ã«ããŽãªãã¿ãŒã²ãããããã¯ããã«å°ãããšãã«æãé¡èã«ãªããŸãã æ¥µç«¯ãªå Žåãæåã®ã«ããŽãªã¯ã«ããŽãª1ã§ã1ã€ã®ãªããžã§ã¯ããš1ã€ã®ïŒåäžã®ïŒå°ã§æ§æãããŸãã ã«ããŽãª1ããä»ã®ã«ããŽãªãžã®ãã¡ã³ã¯ã¿ã¯ããã®ã«ããŽãªããç¹å®ã®ãªããžã§ã¯ããéžæããã ãã§ãã ã¿ãŒã²ããã»ããããèŠçŽ ãéžæããã·ã³ã°ã«ãã³å°ãšã®å®å
šãªé¡äŒŒæ§ããããŸãã äžåçã«æžå°ããæ¥çé¢ã¯ã宿°ãã¡ã³ã¯ã¿ãŒÎcã§èгå¯ãããŸã ã ãœãŒã¹ã«ããŽãªã®åãªããžã§ã¯ããã¿ãŒã²ããã«ããŽãªã®ç¹å®ã®ãªããžã§ã¯ãcã«ããããããã¹ãŠã®å°ãåäžã®å°ID id cã«ãããããŸãã ããã¯ãã©ãã¯ããŒã«ã®ãããªãã®ã§ããã¹ãŠãç¹ç°ç¹ã«åžã蟌ã¿ãŸãã å¶éãšå
±åå¶éã«ã€ããŠè°è«ãããšãããã®ãã¡ã³ã¯ã¿ãŒã®èå¯ã«æ»ããŸãã
ããã°ã©ãã³ã°ã®ãã¡ã³ã¯ã¿ãŒ
ç§ãã¡ã¯å°çãããã°ã©ãã³ã°ã®äžçã«æ»ããŸãã ãããã£ãŠãåãšé¢æ°ã®ã«ããŽãªããããŸãã ãã®ã«ããŽãªãŒãèªåèªèº«ã«ããããããã¡ã³ã¯ã¿ãŒããããããšã³ããã¡ã³ã¯ã¿ãŒãèããŠãã ããã åã«ããŽãªã®å
æ©èœãšã¯äœã§ããïŒ ãŸããããã¿ã€ããå¥ã®ã¿ã€ãã«ãããããŸãã å®éãç§ãã¡ã¯ãã®ãããªãããã³ã°ã«ç²ŸéããŠããŸã;ãããã¯ä»ã®åã«ãã£ãŠãã©ã¡ãŒã¿åãããåã§ãã ããã€ãã®äŸãèŠãŠã¿ãŸãããã
ãã¶ããã¡ã³ã¯ã¿ãŒ
Maybeã®å®çŸ©ã¯ãã¿ã€ãa
ããMaybe
aãžã®ãããã³ã°ã§ãã
data Maybe a = Nothing | Just a
éèŠãªè©³çŽ°ïŒ Maybe
ããèªäœã¯åã§ã¯ãªããåã³ã³ã¹ãã©ã¯ã¿ã§ãã Int
ãBool
ãªã©ã®åãåŒæ°ãšããŠåãåããå¥ã®åãè¿ããŸãã Maybe
ãåŒæ°ãªãã¯åã«é¢ãã颿°ã§ãã ãããã Maybe
ãã¡ã³ã¯ã¿ãŒã§ããããïŒ ïŒä»¥äžãããã°ã©ãã³ã°ã®æèã§ãã¡ã³ã¯ã¿ãŒã«ã€ããŠè©±ããšãããšã³ããã¡ã³ã¯ã¿ãŒã¯ã»ãšãã©åžžã«æå³ãããŸããïŒçµå±ããã¡ã³ã¯ã¿ãŒã¯ãªããžã§ã¯ãïŒããã§ã¯åïŒã®ãããã³ã°ã ãã§ãªããå°ïŒããã§ã¯é¢æ°ïŒã®ãããã³ã°ã§ããããŸãã a
ããb
ãŸã§ã®ãã¹ãŠã®é¢æ°
f :: a -> b
Maybe b
ããMaybe b
ãŸã§ã®é¢æ°ãååŸããããšæããŸãã ãã®ãããªé¢æ°ãå®çŸ©ããã«ã¯ã2ã€ã®Maybe
ã³ã³ã¹ãã©ã¯ã¿ãŒã«å¯Ÿå¿ãã2ã€ã®ã±ãŒã¹ãèæ
®ããå¿
èŠããããŸãã Nothing
ã®å ŽåãåçŽã«Nothing
è¿ããŸãã åŒæ°ãJust
å Žåã颿°f
ããã®ã³ã³ãã³ãã«é©çšããŸãã ãã®ããã Maybe
ã®åœ±é¿äžã«ããf
ã®ã€ã¡ãŒãžã¯é¢æ°ã§ã
f' :: Maybe a -> Maybe b f' Nothing = Nothing f' (Just x) = Just (fx)
ïŒãšããã§ãHaskellã§ã¯ã倿°åã«ã¢ãã¹ãããã£ã䜿çšã§ããŸããããã¯ããã®ãããªå Žåã«éåžžã«äŸ¿å©ã§ããïŒHaskellã§ã¯ãã¢ãŒãã£ãºã ã®è¡šç€ºãæ
åœãããã¡ã³ã¯ã¿ãŒã®å€èгã¯ã髿¬¡fmap
ã«ãã£ãŠå®è£
ãããŸãã Maybe
次ã®ã·ã°ããã£ããããŸãã
fmap :: (a -> b) -> (Maybe a -> Maybe b)

fmap
ã¯é¢æ°ãäžããïŒæã¡äžããïŒãšããèšãããŸãã sublime颿°ã¯ã Maybe
å€ã§æ©èœããŸãã éåžžãã«ãªãŒåã«ããããã®ã·ã°ããã£ã¯2ã€ã®æ¹æ³ã§è§£éã§ããŸãã1ã€ã®å€æ°ã®é¢æ°ãšããŠãããèªäœã颿°(a->b)
ã§ããã颿°ãè¿ã(Maybe a -> Maybe b)
(a->b)
(Maybe a -> Maybe b)
ããŸãã¯2ã€ã®å€æ°ã®é¢æ°ãšããŠã Maybe b
ãè¿ããŸãïŒ
fmap :: (a -> b) -> Maybe a -> Maybe b
äžèšã«åŸã£ãŠã Maybe
fmap
ãå®çŸ©ããŸãã
fmap _ Nothing = Nothing fmap f (Just x) = Just (fx)
Maybe
åã³ã³ã¹ãã©ã¯ã¿ãŒãšfmap
颿°ããã¡ã³ã¯ã¿ãŒãæ§æããŠããããšã瀺ãããã«ã fmap
ãŠãããã¢ãŒãã£ãºã ãšåæãä¿æããããšã蚌æããå¿
èŠããããŸãã ãããã®å£°æã¯ãæ©èœæ³ããšåŒã°ããŸãããã«ããŽãªã®æ§é ãä¿æãããŠããããšãåã«èšŒæãããã®ã§ãã
åçã®å€ææ¹æ³
Haskellã®å
žåçãªèšŒæææ³ã§ããçäŸ¡å€æã®æ¹æ³ã«ãã ã颿°æ³åã蚌æããŸãã ãã®ã¡ãœããã¯ãHaskellã®é¢æ°ãçåŒã®ã»ããã«ãã£ãŠå®çŸ©ãããŠãããšããäºå®ã«äŸåããŠããŸãïŒå·ŠåŽã¯å³åŽã«çãããäž¡æ¹ãçžäºã«çœ®ãæããããšãã§ããŸãïŒç«¶åãé¿ããããã«çœ®æãããšãã«å€æ°ã®ååã倿Žããå¿
èŠãããå ŽåããããŸãïŒã åŒã³åºãã®ä»£ããã«é¢æ°æ¬äœã眮ãæããïŒã€ã³ã©ã€ã³åïŒããæ¬äœã®ä»£ããã«é¢æ°ãåŒã³åºãïŒãªãã¡ã¯ã¿ãªã³ã°ïŒããšãã§ããŸãã äŸãšããŠæç颿°ãèããŸãïŒ
id x = x
ã©ããã§ãããšãã°id y
ã«åºäŒãã°ããã€ã§ãy
ïŒã€ã³ã©ã€ã³åïŒã«çœ®ãæããããšãã§ããŸãã äžè¬ã«ãåŒid (y + 2)
ãªã©id (y + 2)
ã«é©çšãããid
åºçŸã¯ããã®åŒ(y + 2)
眮ãæããããšãã§ããŸãã éæ¹åïŒåŒe
ã¯id e
ïŒãªãã¡ã¯ã¿ãªã³ã°ïŒã«çœ®ãæããããšãã§ããŸãã ãã¿ãŒã³ãããã³ã°ã«ãã£ãŠå®çŸ©ããã颿°ã®å Žåãåå®çŸ©ãåå¥ã«äœ¿çšã§ããŸãã ããšãã°ãäžèšã®fmap
å®çŸ©ã«åŸã£ãŠã fmap f Nothing
ãNothing
ãŸãã¯ãã®éã«çœ®ãæããããšãã§ããŸãã ãã®ã¢ãããŒããå®éã«æ€èšããŠãã ããã ã¢ã€ãã³ãã£ãã£ãç¶æããããšããå§ããŸãããïŒ
fmap id = id
Nothing
ãšJust
2ã€ã®ã±ãŒã¹ãæ€èšããå¿
èŠããããŸãã Nothing
ããå§ããŸãããïŒæ¬äŒŒHaskellã䜿çšããŠãçåŒã®å·ŠåŽããå³åŽãžã®å€æã«ã€ããŠèª¬æããŸãïŒã
fmap id Nothing = { fmap } Nothing = { id } id Nothing
2çªç®ã®ã¹ãããã§ãå察æ¹åã®id
ã®å®çŸ©ã䜿çšããŠã id Nothing
代ããã«id Nothing
ã眮ãæããããšã«æ³šæããŠãã ããã å®éã«ã¯ããã®ãããªèšŒæ ã¯ãããã®å Žåã¯Nothing
ãšããåã衚çŸã§äŒè°ãçãäžã«ãªããŸã§ãã䞡端ããè¯ãçããããšããæ¹æ³ã«ãã£ãŠè¡ãããŸãã 2çªç®ã®ã±ãŒã¹ãç°¡åã§ãã
fmap id (Just x) = { fmap } Just (id x) = { id } Just x = { id } id (Just x)
fmap
ãã³ã³ããžã·ã§ã³ãä¿åããããšã瀺ããŸãïŒ
fmap (g . f) = fmap g . fmap f
Nothing
ã±ãŒã¹ããå§ããŸãããã
fmap (g . f) Nothing = { fmap } Nothing = { fmap } fmap g Nothing = { fmap } fmap g (fmap f Nothing)
ããã§ã¯Just
ã®æéã§ãã
fmap (g . f) (Just x) = { fmap } Just ((g . f) x) = { } Just (g (fx)) = { fmap } fmap g (Just (fx)) = { fmap } fmap g (fmap f (Just x)) = { } (fmap g . fmap f) (Just x)
C ++ã¹ã¿ã€ã«ã®å¯äœçšãæã€é¢æ°ã§ã¯ãåçã®å€ææ¹æ³ãæ©èœããªãããšã匷調ãã䟡å€ããããŸãã äŸãèããŠã¿ãŸãããïŒ
int square(int x) { return x * x; } int counter() { static int c = 0; return c++; } double y = square(counter());
åçã®å€ææ¹æ³ã§ã¯ã square
ãå±éããŠååŸã§ããŸã
double y = counter() * counter();
ééããªãããã®ãããªå€æã¯æ£ãããªããåŒã®çµæã倿ŽããŸãã ããã«ããããããã square
ãã¯ããšããŠå®çŸ©ãããŠããå ŽåãC ++ããªããã»ããµãŒã¯åçã®å€ææ¹æ³ã䜿çšããŠãæ²æšãªçµæããããããŸãã
ãã¶ããŸã
ãã¡ã³ã¯ã¿ã¯Haskellã§ç°¡åã«è¡šçŸã§ããŸãããäžè¬åããã°ã©ãã³ã°ãšé«é颿°ããµããŒãããä»»æã®èšèªã§èšè¿°ããããšãã§ããŸãã optional
ã®ãã³ãã¬ãŒãã¿ã€ãã§ããMaybeã®C ++ã¢ããã°ãèããŠã¿ãŸãããã 以äžã«å®è£
ã®ã¹ã±ããã瀺ããŸãïŒå®å
šãªå®è£
ã¯ãåŒæ°ãæž¡ãããŸããŸãªæ¹æ³ãã³ããŒã»ãã³ãã£ã¯ã¹ãããã³C ++ãªãœãŒã¹ç®¡çã«åºæã®ãã®ä»ã®åé¡ãæç€ºçã«èª¬æããŠãããããã¯ããã«è€éã§ãïŒã
template<class T> class optional { bool _isValid;
äžèšã®ãã³ãã¬ãŒãã¯ããã¡ã³ã¯ã¿ãŒã®èª¬æã®ååã§ããã¿ã€ããããã³ã°ãæäŸããŸãã æ°ããã¿ã€ãã®optional<T>
åã¿ã€ãT
ã«ãããããŸãT
次ã«ã颿°ã«å¯Ÿããã¢ã¯ã·ã§ã³ã説æããŸãã
template<class A, class B> std::function<optional<B>(optional<A>)> fmap(std::function<B(A)> f) { return [f](optional<A> opt) { if (!opt.isValid()) return optional<B>{}; else return optional<B>{ f(opt.val()) }; }; }
ããã¯ã颿°ãåŒæ°ãšããŠåãåãã颿°ãè¿ãé«é颿°ã§ãã ãããŠãã«ã¬ãŒãªãã®å¥ã®ãªãã·ã§ã³ããããŸãïŒ
template<class A, class B> optional<B> fmap(std::function<B(A)> f, optional<A> opt) { if (!opt.isValid()) return optional<B>{}; else return optional<B>{ f(opt.val()) }; }
ãŸãã¯ã optional
ãã³ãã¬ãŒãã¡ãœãããšããŠfmap
ãå®è£
ã§ããŸãã ãã®ãããªéžæã®ãããŸããã«ãããC ++ã®ããã¡ã³ã¯ã¿ãŒããã¿ãŒã³ã®æœè±¡åãåé¡ã«ãªããŸãã ãã¡ã³ã¯ã¿ãç¶æ¿ããã«ã¯ããã¡ã³ã¯ã¿ãã€ã³ã¿ãŒãã§ãŒã¹ã«ããå¿
èŠããããŸãïŒæ®å¿µãªããããã³ãã¬ãŒã颿°ã¯ä»®æ³åã§ããŸããïŒã ãããšããç¡æã®ãã³ãã¬ãŒã颿°ãã«ã¬ãŒãã©ããïŒ C ++ã³ã³ãã€ã©ã¯æ¬ èœããŠããåãæ£ããæšæž¬ã§ããŸããããŸãã¯æç€ºçã«èšå®ããå¿
èŠããããŸããïŒ å
¥å颿°f
ãint
ãbool
倿ãããšæ³åããŠãã ããã ã³ã³ãã€ã©ãŒãã¿ã€ãg
決å®ããæ¹æ³ïŒ
auto g = fmap(f);
ç¹ã«å°æ¥ã fmap
ããŒãžã§ã³ã§å€ãã®ãã¡ã³ã¯ã¿ãŒãååšããå Žåã¯ïŒ ïŒä»ã®ã¿ã€ãã®ãã¡ã³ã¯ã¿ãŒã«ã€ããŠã¯ããã«ç¥ãããšãã§ããŸããïŒ
åã¯ã©ã¹
ãã¡ã³ã¯ã¿ã®æœè±¡åã¯Haskellã§ã©ã®ããã«å®è£
ãããŠããŸããïŒ åã¯ã©ã¹ã®ã¡ã«ããºã ã䜿çšãããŸãã åã¯ã©ã¹ã¯ãåäžã®ã€ã³ã¿ãŒãã§ãŒã¹ããµããŒãããåã®ãã¡ããªãŒãå®çŸ©ããŸãã ããšãã°ãåçæ§ã«å¹æµãããªããžã§ã¯ãã®ã¯ã©ã¹ã¯æ¬¡ã®ããã«å®çŸ©ãããŸãã
class Eq a where (==) :: a -> a -> Bool
åa
2ã€ã®åŒæ°ãåãã Bool
ãè¿ãæŒç®å(==)
ãµããŒãããå Žåãåa
ã¯ã¯ã©ã¹Eqã«å±ãããšäž»åŒµããŸãã ç¹å®ã®åãEq
ã«é¢é£ããŠããããšãHaskellã«çŽåŸãããã«ã¯ãã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ ïŒã€ã³ã¹ã¿ã³ã¹ãå®è£
ïŒãšããŠå®£èšããå®è£
(==)
ãæäŸããå¿
èŠããããŸãã ããšãã°ããã®ãããªå¹³é¢äžã®ç¹ã®å®çŸ©ïŒ2ã€ã®Float
åç©ïŒïŒ
data Point = Pt Float Float
ç¹ã®ç䟡æ§ã倿ããããšãå¯èœã§ãïŒ
instance Eq Point where (Pt xy) == (Pt x' y') = x == x' && y == y'
ããã§ãå®çŸ©ãããæŒç®å(==)
ã¯ã2ã€ã®ãã¿ãŒã³(Pt xy)
ãš(Pt x' y')
éã«æ¿å
¥ãããŠããŸãã 颿°ã®æ¬äœã¯=
èšå·ã®å³åŽã«é
眮ãããŸãã Point
Eq
ã€ã³ã¹ã¿ã³ã¹ãšããŠå®£èšãããåŸã Point
çãããã©ãããçŽæ¥æ¯èŒã§ããŸãã C ++ãJavaãšã¯ç°ãªãã Point
ãå®çŸ©ãããšãã«ã¯ã©ã¹ãEq
ã€ã³ã¿ãŒãã§ã€ã¹ãæäŸããå¿
èŠã¯ãªãããšã«æ³šæããŠãã ãã-ããã¯åŸã§è¡ãããšãã§ããŸãã Haskellã§é¢æ°ïŒããã³æŒç®åïŒããªãŒããŒããŒãããããã®ã¡ã«ããºã ã¯ãåã¯ã©ã¹ã ãã§ããããšã«æ³šæããŠãã ããã ããŸããŸãªãã¡ã³ã¯ã¿ãŒã®fmap
ããªãŒããŒããŒãããããã«å¿
èŠã§ãã 埮åŠãªç¹ã1ã€ãããŸãããã¡ã³ã¯ã¿ã¯åãšããŠã§ã¯ãªããåã«å¯Ÿãã颿°ãåã³ã³ã¹ãã©ã¯ã¿ãšããŠå®çŸ©ãããŸãã åã¯ã©ã¹ã¯ã Eq
ã®å Žåã®ããã«ãåã ãã§ãªããåã³ã³ã¹ãã©ã¯ã¿ã®ãã¡ããªãŒãèšè¿°ããå¿
èŠããããŸãã 幞ããªããšã«ãHaskellã®åã¯ã©ã¹ã¡ã«ããºã ã¯åçŽãªåã ãã§ãªãåã³ã³ã¹ãã©ã¯ã¿ãŒã§ãæ©èœããŸãïŒ PPïŒé¢æ°åãã©ãã€ã ã«åŸãè¯ãäŸ-颿°åã®äžçã«ãããŠãããªããžã§ã¯ãããæªãã¯ãããŸãã ïŒã Functor
ã¯ã©ã¹ã®å®çŸ©ã¯æ¬¡ã®ãšããã§ãã
class Functor f where fmap :: (a -> b) -> fa -> fb
äžãããã眲åãæã€fmap
颿°ãããå Žåã f
ã¯Functorã§ãããšäž»åŒµããŸãã ããã§ã f
ã¯mã§ããã m ãšåãçš®é¡ã®æ°ãã倿°ãšãæ°ãã倿°a
ããã³b
ã§ãã ããããã³ã³ãã€ã©ã¯f
ãåã³ã³ã¹ãã©ã¯ã¿ã§ããããšãçè§£ã§ãããã®äœ¿çšã远跡ããŸããä»ã®åãããã§ã¯fa
ããã³fb
é©çšããŸãã ãããã£ãŠãMaybeã®å Žåã®ããã«ããã¡ã³ã¯ã¿ãŒã®ã€ã³ã¹ã¿ã³ã¹ãšããŠå®£èšããã®ã¯åã³ã³ã¹ãã©ã¯ã¿ãŒã§ãã
instance Functor Maybe where fmap _ Nothing = Nothing fmap f (Just x) = Just (fx)
Functor
ã¯ã©ã¹ãšãã€ã³ã¹ã¿ã³ã¹Maybe
ãå«ãå€ãã®äžè¬çãªåã®å®£èšãPreludeæšæºã©ã€ãã©ãªã«å«ãŸããŠããããšã«æ³šæããŠãã ããã
C ++ã®ãã¡ã³ã¯ã¿ãŒ
C ++ã§åãã¢ãããŒããé©çšã§ããŸããïŒ åã³ã³ã¹ãã©ã¯ã¿ã¯optional
ãªã©ã®ãã³ãã¬ãŒãã¯ã©ã¹ã«å¯Ÿå¿ããããããã³ãã¬ãŒããã©ã¡ãŒã¿F
ã䜿çšããŠfmap
2åãã©ã¡ãŒã¿åããå¿
èŠããããŸãF
次ã®ããã«æžãããŠããŸãã
template<template<class> F, class A, class B> F<B> fmap(std::function<B(A)>, F<A>);
ãããããã®ãã³ãã¬ãŒããããŸããŸãªãã¡ã³ã¯ã¿ãŒã«ç¹åããã«ã¯ã©ãããã°ããã§ããããïŒ æ®å¿µãªãããC ++ãã³ãã¬ãŒã颿°ã®éšåçãªç¹æ®åã¯çŠæ¢ãããŠããŸãã ããªãã¯æžãããšãã§ããŸããïŒ
template<class A, class B> optional<B> fmap<optional>(std::function<B(A)> f, optional<A> opt)
代ããã«ã颿°ã®ãªãŒããŒããŒãã«æ»ãå¿
èŠããããŸãããã®çµæã fmap
ã®å
ã®å®çŸ©ã«æ»ããŸãïŒã«ãªãŒåããã«ïŒã
template<class A, class B> optional<B> fmap(std::function<B(A)> f, optional<A> opt) { if (!opt.isValid()) return optional<B>{}; else return optional<B>{ f(opt.val()) }; }
ãã®å®çŸ©ã¯æ©èœããŸãããé©åãªãªãŒããŒããŒããè¡ãã«ã¯2çªç®ã®åŒæ°ãå¿
èŠã§ãã fmap
ã®ããäžè¬çãªå®çŸ©fmap
åã«ç¡èŠãããŸãã
ãã¡ã³ã¯ã¿ãŒãªã¹ã
ããã°ã©ãã³ã°ã«ããããã¡ã³ã¯ã¿ãŒã®éèŠæ§ãããããçè§£ããã«ã¯ãããã«äŸãæ€èšããŠãã ããã å¥ã®åã«ãã£ãŠãã©ã¡ãŒã¿ãŒåãããåã¯ããã¡ã³ã¯ã¿ãŒã®åœ¹å²ã®åè£ã§ãã ããšãã°ãäžè¬åãããã³ã³ããã¯ãèŠçŽ ã®ã¿ã€ãã«ãã£ãŠãã©ã¡ãŒã¿åãããŸã;ãªã¹ããéåžžã«åçŽãªã³ã³ãããèããŠãã ããïŒ
data List a = Nil | Cons a (List a)
ããã«ã¯ã List
åã³ã³ã¹ãã©ã¯ã¿ããããŸããããã¯ãä»»æã®åa
ããList a
ãžã®ãããã³ã°ã§ãã List
ããã¡ã³ã¯ã¿ãŒã§ããããšã瀺ãããã«ããã¡ã³ã¯ã¿ãŒã«æ²¿ã£ã颿°ã®ãªããã£ã³ã°ãå®çŸ©ããå¿
èŠããããŸãã ç¹å®ã®é¢æ°a->b
List a -> List b
a->b
List a -> List b
a->b
å®çŸ©ããŸãã
fmap :: (a -> b) -> (List a -> List b)
List
æ©èœãã颿°ã¯ã2ã€ã®ãªã¹ãã³ã³ã¹ãã©ã¯ã¿ãŒã«ã€ããŠããããã2ã€ã®ã±ãŒã¹ãèæ
®ããå¿
èŠããããŸãã Nil
ã®å Žåã¯äºçްãªããšã§ãNil
ãè¿ãããŸãã空ã®ãªã¹ãããå€ããçµãåºãããšã¯ã§ããŸããã Cons
ã±ãŒã¹ã¯ãååž°ã«åœ±é¿ããããã Cons
ã«ããã§ãã èããŠã¿ãŸãããããããã£ãŠããªã¹ãa
ã颿°f
ãa
ãb
ã«å€æãããªã¹ãb
ãååŸããããšããŸãã åœç¶ã f
ã䜿çšããŠåãªã¹ãé
ç®ãa
ããb
ã«å€æããå¿
èŠããããŸãã ïŒç©ºã§ãªãïŒãªã¹ããé ãšå°Ÿã®Cons
ãšããŠå®çŸ©ãããŠããå Žåãæ£ç¢ºã«äœãããå¿
èŠããããŸããïŒ f
ãé ã«é©çšããéèµ·ããïŒfmapã§æ¬ ããïŒ f
ãå°Ÿã«é©çšããŸãã ãã®å®çŸ©ã¯ååž°çã§ããraisedfããraised f
ãŸã§ãå®çŸ©ããŸãã
fmap f (Cons xt) = Cons (fx) (fmap ft)
fmap f
ã®å³åŽã§ã fmap f
ãå®çŸ©ãããã®ãããçããªã¹ããã€ãŸãåŸè
ã®æ«å°Ÿã«é©çšãããããšãéèŠã§ãã ããçããªã¹ãã«ååž°ãé©çšãããããå¿
ç¶çã«ç©ºã®ãªã¹ãããŸãã¯Nil
ãŸãã ãããããã§ã«æ±ºå®ããããã«ã Nil
fmap f
ã¯Nil
ãäžããããã«ããååž°ãå®äºããŸãã Consã³ã³ã¹ãã©ã¯ã¿ãŒã䜿çšããŠãæ°ãããããïŒ fx
ïŒãšæ°ããããŒã«ïŒ fmap ft
ïŒãçµã¿åãããããšã«ãããæçµçµæãåŸãããŸãã ãã®çµæããã¡ã³ã¯ã¿ã®ã€ã³ã¹ã¿ã³ã¹ãšããŠã®ãªã¹ãã®å®å
šãªå®£èšã¯æ¬¡ã®ãšããã§ãã
instance Functor List where fmap _ Nil = Nil fmap f (Cons xt) = Cons (fx) (fmap ft)
C ++ã«æ
£ããŠããå Žåã¯ã std::vector
ãæ€èšããã®ãçã«ããªã£ãŠããŸããããã¯åºæ¬çã«åºæ¬çãªC ++ã³ã³ãããŒã§ãã std::vector
ã®fmap
å®è£
ã¯ã std::transform
åãªãã©ãããŒã§ãïŒ
template<class A, class B> std::vector<B> fmap(std::function<B(A)> f, std::vector<A> v) { std::vector<B> w; std::transform( std::begin(v) , std::end(v) , std::back_inserter(w) , f); return w; }
ãã®å©ããåããŠãããšãã°ãäžé£ã®æ°åã2ä¹ããããšãã§ããŸãã
std::vector<int> v{ 1, 2, 3, 4 }; auto w = fmap([](int i) { return i*i; }, v); std::copy( std::begin(w) , std::end(w) , std::ostream_iterator(std::cout, ", "));
ã»ãšãã©ã®C ++ã³ã³ãããŒã¯ãæ¬è³ªçã«ãã¡ã³ã¯ã¿ãŒã§ãã ããã¯ã fmap
ããªããã£ããªçžå¯Ÿã§ããstd::transform
æž¡ãããšãã§ããå埩åã®ååšã«ãã£ãŠä¿èšŒãããŸãã æ®å¿µãªããããã¡ã³ã¯ã¿ãŒã®åçŽãã¯ãã€ãã¬ãŒã¿ãŒãšäžæå€æ°ïŒäžèšã®fmap
å®è£
ã®ããã«ïŒã®ãŽãã®äžã§å€±ãããŸãã è¯ããã¥ãŒã¹ãã-C ++ã«å«ããäºå®ã®ç¯å²ã®ã©ã€ãã©ãªã¯ããã®ééãæ©èœçãªæ§è³ªã倧å¹
ã«æããã«ããŸãã
ãªãŒããŒãã¡ã³ã¯ã¿ãŒ
ããçš®ã®çŽèгãç¹ã«ãã¡ã³ã¯ã¿ãäœããã®ã³ã³ããã§ãããšããããšãéçºããã®ã§ãããã§ã¯äžèŠå®å
šã«ç°ãªãäŸã§ãã ã¿ã€ãa
ããa
ãè¿ã颿°ã®ã¿ã€ããžã®ãããã³ã°ãæ€èšããŠãã ããã é©åãªçè«ã¬ãã«ããã³ã«ããŽãªã¬ãã«ã§ã®æ©èœã¿ã€ãã®è°è«ã«ã¯ãŸã å°éããŠããŸããããããã°ã©ããšããŠããããã«ã€ããŠããçšåºŠçè§£ããŠããŸãã Haskellã§ã¯ã颿°åã¯ãåã³ã³ã¹ãã©ã¯ã¿ãŒã§ããç¢å°(->)
ã䜿çšããŠæ§ç¯ãããŸããç¢å°(->)
ã¯ãåŒæ°åãšçµæåã®2ã€ã®åãåããŸãã æ¢ã«äžçœ®èšæ³a->b
ã§ãããæºãããŠããããæ¬åŒ§ã䜿çšãããšæ¥é èŸèšæ³ã䜿çšã§ããŸãã
(->) ab
éåžžã®é¢æ°ãšåæ§ã«ãm ããã³ããã€ãã®åŒæ°ã®æ°ãã颿°ãéšåçã«é©çšã§ããŸãã ãããŠãç¢å°ã«1ã€ã®åŒæ°ãäžãããšãããŸã å¥ã®åŒæ°ãåŸ
ã£ãŠããŸãã ã€ãŸãã
(->) a
åã³ã³ã¹ãã©ã¯ã¿ã§ãã æ¬æ Œçãªã¿ã€ãa->b
ãååŸããã«ã¯ããã1ã€ã®ã¿ã€ãb
ãå¿
èŠã§ãã ãããã£ãŠãç¢å°ã¯ãã«ãã£ãŠãã©ã¡ãŒã¿åããa
ã¿ã€ãã³ã³ã¹ãã©ã¯ã¿ãŒã®ãã¡ããªå
šäœãå®çŸ©ããŸãã ãã¡ã³ã¯ã¿ã®ãã¡ããªãŒã§ããããã©ããã調ã¹ãŠã¿ãŸãããã 2ã€ã®ãã©ã¡ãŒã¿ãŒãæ··åããªãããã«ããããã®ååã倿ŽããŠã圹å²ã匷調ããŸãã ãã¡ã³ã¯ã¿ãŒã®ä»¥åã®å®çŸ©ã«åŸã£ãŠãåŒæ°ã®åã¯r
ãšåŒã°ããçµæã®åã¯a
ã§ãã ãããã£ãŠãã³ã³ã¹ãã©ã¯ã¿ãŒã¯ä»»æã®ã¿ã€ãã®a
åããã¿ã€ãr->a
ãããããŸãã æ©èœãæ£åœåããããã«ã颿°a->b
ãr->a
ãåãåãr->b
ãè¿ã颿°ã«äžããå¿
èŠããããŸãã ãããã¯b
ããããb
ãšb
ã®ã³ã³ã¹ãã©ã¯ã¿ã¢ã¯ã·ã§ã³(->) r
ã«ãã£ãŠäœæãããã¿ã€ãã§ãã ããã¯çœ²åfmap
ã§ãïŒ
fmap :: (a -> b) -> (r -> a) -> (r -> b)
颿°f::a->b
ãšé¢æ°g::r->a
ã r->b
äœæããg::r->a
ããºã«ã®ãããªãã®ãåŸãããŸãã ããããæ§æããæ¹æ³ã¯1ã€ãããªããçµæã¯ãŸãã«å¿
èŠãªãã®ã§ãã ãã®ãããªfmap
å®è£
ã倿ããŸãã
instance Functor ((->) r) where fmap fg = f . g
ããŸããããŸããïŒ ããããªã¹ãã¯ããã¬ãã£ãã¯ã¹åœ¢åŒã䜿çšããŠã¬ã³ãŒããççž®ã§ããŸãã
fmap fg = (.) fg
åŒæ°ãçç¥ããŠã2ã€ã®é¢æ°ãèå¥ã§ããããã«ãªããŸããã
fmap = (.)
åã³ã³ã¹ãã©ã¯ã¿(->) r
ãšfmap
ãã®ãããªå®è£
ã®çµã¿åããã¯ãããªãŒããŒããšåŒã°ããŸãã
ã³ã³ãããšããŠã®ãã¡ã³ã¯ã¿ãŒ
ããã°ã©ãã³ã°ã§ãã¡ã³ã¯ã¿ãŒã䜿çšããŠæ±çšã³ã³ãããŒãå®çŸ©ããäŸããŸãã¯å°ãªããšããã¡ã³ã¯ã¿ãŒããã©ã¡ãŒã¿ãŒåããåã®å€ãå«ããªããžã§ã¯ããå®çŸ©ããäŸã«ã€ããŠç¥ããŸããã 颿°ãããŒã¿ãšã¯èããŠããªãããããªãŒããŒãã¡ã³ã¯ã¿ãŒã¯äŸå€ã®ããã§ãã ãã ãããããŸã§èŠãŠããããã«ãèšç®ãããŒãã«ã®æ€çŽ¢ã«éå®ãããå Žåãã¡ã¢åã¯é¢æ°ã«é©çšã§ããŸãã ããŒãã«ã¯ãã§ã«ããŒã¿ã§ãã äžæ¹ãHaskellã¯é
å»¶ããŠããããããªã¹ãã®ãããªåŸæ¥ã®ã³ã³ãããŒã¯å®éã«ã¯é¢æ°ãšããŠå®è£
ã§ããŸãã ããšãã°ã次ã®ããã«èª¬æã§ããèªç¶æ°ã®ç¡éãªã¹ããèŠãŠãã ããã
nats :: [Integer] nats = [1..]
æåã®è¡ã®è§æ¬åŒ§ã®ãã¢ã¯ããªã¹ãçšã®çµã¿èŸŒã¿t ããã³æ°ããHaskellã³ã³ã¹ãã©ã¯ã¿ãŒã§ãã 2è¡ç®ã§ã¯ãæ¬åŒ§ã䜿çšããŠãªã¹ããªãã©ã«ã圢æããŸãã æããã«ãã¡ã¢ãªå
ã«ãã®ãããªç¡éã®ãªã¹ããé
眮ããããšã¯äžå¯èœã§ãã 代ããã«ãã³ã³ãã€ã©ã¯èŠæ±ã«å¿ããŠæŽæ°ãçæãã颿°ãäœæããŸãã Haskell : , , . , , , . strlen
, . , . , , , , ! ( ) ( ), . C++, â std::future
, - , ; , , , . IO
Haskell, , âHello World!â . , , , . . , , â . , â . , â , , , , . , , , a
:
data Const ca = Const c
Const
, c
a
. , , , (->)
.
fmap :: (a -> b) -> Const ca -> Const cb
, fmap
, â :
instance Functor (Const c) where fmap _ (Const v) = Const v
C++ ( , !), , , , .
template<class C, class A> struct Const { Const(C v) : _v(v) {} C _v; };
C++ - fmap
, Const
, .
template<class C, class A, class B> Const<C, B> fmap(std::function<B(A)> f, Const<C, A> c) { return Const<C, B>{c._v}; }
, Const
. Î c , â . .
, , . , , , . , , . . , . maybeTail
( : )? , Haskell:
maybeTail :: [a] -> Maybe [a] maybeTail [] = Nothing maybeTail (x:xs) = Just xs
( , Nil
[]
. Cons
:
().) maybeTail
, Maybe
[]
, a
. fmap
, f
: Maybe list
? . fmap
, Maybe
. f
Maybe
, f
. ( fmap f
), . , Maybe list
:
square x = x * x mis :: Maybe [Int] mis = Just [1, 2, 3] mis2 = fmap (fmap square) mis
, , fmap
Maybe
, , â list
. , , :
mis2 = (fmap . fmap) square mis
, fmap
:
fmap :: (a -> b) -> (fa -> fb)
, fmap
(fmap . fmap)
square :: Int -> Int
[Int] -> [Int]
fmap
Maybe [Int] -> Maybe [Int]
mis
. , , fmap
fmap
. : , ( , ). , , , . , . ? , , . . , , . , Cat
( , ). "" , , -, , . , "". , , , . , .
æŒç¿
- `Maybe` ,
fmap _ _ = Nothing
? (: ) - `reader` (: ).
- reader (, , Haskell).
- . , ( ).
è¬èŸ
. .
leshabirukov : Bodigrim , . .