#blognavi
#blognavi
(副題・ラムダの森の青い鳥)
前回のエントリで
檜山さんの「世界一やさしいモナド入門」とフォローの、
「モナドを構成する三つ組のうちの一つ (ext) に直接対応するHaskell関数が見つからない」と書いたトコロ、
はてなブックマークで
檜山さんの「世界一やさしいモナド入門」とフォローの、
「モナドを構成する三つ組のうちの一つ (ext) に直接対応するHaskell関数が見つからない」と書いたトコロ、
はてなブックマークで
「(=<<)なんじゃない?」
という指摘を受けました。
ご存知のとおり(あるいは字面からのご想像のとおり)
本来この関数の使い道は
本来この関数の使い道は
getLine >>= putStrLn
と書くところで 左右逆に
putStrLn =<< getLine
と書けるようにしただけのもので、
今まで「ごくまれに便利かも知れないユーティリティ関数」
程度の認識でした。
今まで「ごくまれに便利かも知れないユーティリティ関数」
程度の認識でした。
しかしこの演算子の型は当然、
(>>=) :: M a -> (a -> Mb) -> M b
の第1引数と第2引数を入れ替えた
(=<<) :: (a -> Mb) -> M a -> M b
なわけで
さらに、略された右結合の括弧を書き加えると
さらに、略された右結合の括弧を書き加えると
(=<<) :: (a -> M b) -> (M a -> M b)
これは求めるext関数の型です。
外面だけでなく、今度は関数の意味するところを考えてみます。
(=<<)は本来2項演算子ですがHaskellですからもちろんカリー化されているわけで、
第一引数にfを代入した状態(f=<<)の意味を考えてみると、
第一引数にfを代入した状態(f=<<)の意味を考えてみると、
「モナドを受け取ってfを適用してモナドを返す関数(M a -> M b)」
まさにfをextで拡張した関数となっています。
まさにfをextで拡張した関数となっています。
あとは実験あるのみ。
bb.hs
module Main where import Monad -- (>>=) を(=<<)で作ってみる。 -- m >>= f = (ext f) $ m のextに(=<<)を入れればよい。 (>>=>) :: Monad m => m a -> (a -> m b) -> m b m >>=> f = ((=<<) f) $ m --↑よくみたら 引数の順序入れ替えてるだけだ! -- (>>=) のかわりに使ってみる。 main = getLine >>=> putStrLn
Prelude> :l bb.hs
Main> main
abcd ←キー入力
abcd ←出た
Main> main
abcd ←キー入力
abcd ←出た
、、、大丈夫みたいです。
檜山さんのエントリのコメント欄やはてなブックマークを
よくよくみれば(=<<)は最初のほうから指摘されていたんですよね orz
よくよくみれば(=<<)は最初のほうから指摘されていたんですよね orz
カテゴリ: [プログラミング] - &trackback() - 2006年04月20日 21:23:34