FunctorとMonadの間にあるApplicative第3回でFunctorクラスとMonadクラスを紹介しましたが,ここ数年の間に,FunctorクラスとMonadクラスの関係に少し変化が起こりました。Functorクラスよりも強く,Monadクラスよりも弱いクラス,すなわちFunctorクラスとMonadクラスの中間に相当するApplicativeクラスが現れ,広く使われるようになったのです。パーサー・ライブラリでは,Applicativeクラスおよび「Applicative版のMonoid」であるAlternativeクラスが欠かせないものになっています。第48回でのparTraversable関数の説明,および第50回で取り上げたparMap関数/parMapM関数の定義の文脈部分で登場したTraversableクラスも,Applicativeとのかかわりが深いクラスです。Applicativeに対する理解は,今やHaskellで実用的なプログラムを書くうえでは避けて通れません。今回は,Applicativeクラスについて詳しく説明していきます。Functorに追加される関数Applicativeクラスの追加に伴って,Functorクラスの定義も少し変化しました。Applicativeクラスを説明する前に,Functorクラスの変化について説明しておきましょう。Data.Functorモジュールでは,fmapメソッドの別名として<$>演算子が提供されています。fmapまた,Functorクラスのメソッドとして<$演算子が追加され,Data.Functorでエクスポートされています。constFunctorクラスでは<$演算子に対しデフォルトの定義を与えているので,Functorクラスのインスタンスで<$演算子を定義する必要はありません。したがって,Functorクラスに対する<$演算子の追加が,既存のFunctorクラスのインスタンスや,新たにFunctorクラスのインスタンスを定義する際に影響を及ぼすことはありません。Functorクラスのインスタンスで<$演算子の効率的な実装を提供できるのであれば,<$演算子のデフォルトの定義を上書きしてもかまいません。<$演算子は,Functorクラスのインスタンスとして定義されたStateやIOのようなコンテナの中の値を,第1引数で与えられた値に置き換えて返します。(11,"string")1番目と2番目の例はIOというコンテナの例で,3番目は第6回で説明したStateモナドのStateというコンテナの例です。Stateモナドでは,put関数を使って「状態」を更新します。"string"」でStateというコンテナの「状態」はstringという文字列になりますが,コンテナの値は()になります。"string")((),"string")このコンテナの値を,<$演算子を使って()から11に置き換えているのです。"string"」という処理自体には影響しないことに注意してください。<$演算子は,複数の計算から一つの大きな計算を組み立てる際,組み立てる計算の中に何らかの作用を持つ計算を組み込むのに役立ちます。"string")"string"121この例では,複数の計算から一つの大きな計算を組み立てるのに,Monadクラスのreturnメソッドや,第17回で説明したControl.Monadモジュールのap関数を利用しています。Functorクラスが提供するメソッドには,liftM関数に相当する関数の持ち上げ機能がありますが,持ち上げた関数に適切な引数を渡す機能はメソッドとして提供されていません。このため,関数を適用できるコンテナに値を格納するためにreturnメソッドを利用したり,<$>演算子で持ち上げた関数を「コンテナに包まれた値」に適用するためにap関数を使ったりしているのです。bFunctorクラス単体の能力はとても弱いため,複数の計算からなる一つの大きな計算を組み立てるには,このようにMonadなどの助けを借りる必要があります。農家が実感した自動飛行ドローンのすごさクラウド現場の負担軽減を!医療界でのAWS活用法SaaS導入で重要なID管理のコツとは?クラウドの新形態「aPaaS」のメリットDXを阻むコミュニケーションの壁とは?AWSとSAPの連携強化がもたらす利点はデジタル自治体では何が実現できるのか?500万社が導入。価値創造型の社内コミュニケーションとは発想を豊かにする有機的な会議ツールとは働き方が変わる。Reserved.このページに掲載されている記事・写真・図表などの無断転載を禁じます。掲載している情報は、記事執筆時点のものです。