今日の一行 – ポイントフリースタイルを参考にして mytake から引数を消してみる。
mytake n xs = fst $ mysplitAt n xs ↓ mytake n xs = fst (mysplitAt n xs) ↓ 関数合成を使って xs を外に追い出す mytake n xs = (fst . (mysplitAt n)) xs ↓ xs を消す mytake n = (fst . (mysplitAt n)) ↓ 関数合成演算子を前置 mytake n = (.) fst (mysplitAt n) ↓ もう一度,関数合成演算子を使って今度は n を追い出す mytake n = (((.) fst) . mysplitAt) n ↓ n を消す mytake = ((.) fst) . mysplitAt
結果。
*Main> mytake 2 [1,2,3,4] [1,2]
おお!うまくいった!すごいな。
ポイントは関数合成とその演算子を前置するところだな。
んー,待てよ。単純にこうやったらどうだ?
mytake = fst . mysplitAt
*Main> :l mysplitAt.hs Compiling Main ( mysplitAt.hs, interpreted ) mysplitAt.hs:25:20: Couldn't match `(a, b)' against `t -> t1' Expected type: (a, b) Inferred type: t -> t1 Expected type: Int -> (a, b) Inferred type: Int -> [a1] -> ([a1], [a1]) In the second argument of `(.)', namely `mysplitAt' Failed, modules loaded: none.
だめか。
そうか, (.) fst が関数を引数にとる関数で,これと mysplitAt を合成すると,mysplitAt の引数が外に追い出されるんだ。つまりこう。
mytake n xs = (((.) fst) . mysplitAt) n xs
で,引数が消える,と。
http://oss.timedia.co.jp/index.fcgi/kahua-web/show/ossz/oneline/2006-05-01
のコメントにも書きましたが,演算子の前置はやらなくてもできます.
mytake n = fst . (mysplitAt n)
↓
mytake n = (fst .) (mysplitAt n)
↓
mytake n = ((fst .) . mysplitAt) n
↓
mytake = (fst .) . mysplitAt