Haskellの駄目な使い方

決定版:モナド3点セット(M,ext,unit)に対応するHaskell関数

最終更新:

匿名ユーザー

- view
メンバー限定 登録/ログイン
#blognavi
(副題・ラムダの森の青い鳥)

前回のエントリ
檜山さんの「世界一やさしいモナド入門」フォローの、
「モナドを構成する三つ組のうちの一つ (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を適用してモナドを返す関数(M a -> M b)」
まさに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 ←出た

、、、大丈夫みたいです。


檜山さんのエントリのコメント欄やはてなブックマークを
よくよくみれば(=<<)は最初のほうから指摘されていたんですよね orz



カテゴリ: [プログラミング] - &trackback() - 2006年04月20日 21:23:34
名前: コメント:
#blognavi
目安箱バナー